diff --git a/aspnetcore/blazor/advanced-scenarios.md b/aspnetcore/blazor/advanced-scenarios.md index 98c926de7883..e74853cbc8df 100644 --- a/aspnetcore/blazor/advanced-scenarios.md +++ b/aspnetcore/blazor/advanced-scenarios.md @@ -37,7 +37,7 @@ In methods wi ```razor @page "/built-content" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer

Build a component

diff --git a/aspnetcore/blazor/call-web-api.md b/aspnetcore/blazor/call-web-api.md index 7a9f019543f2..dd95d295eaeb 100644 --- a/aspnetcore/blazor/call-web-api.md +++ b/aspnetcore/blazor/call-web-api.md @@ -64,13 +64,13 @@ The Blazor examples that demonstrate obtaining weather data from a server API ar For server-side components in Blazor Web Apps that require interactivity, add Interactive Server rendering to the component: ```razor -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer ``` For client-side components in Blazor Web Apps that require interactivity, add Interactive WebAssembly rendering to the component: ```razor -@rendermode RenderMode.InteractiveWebAssembly +@rendermode InteractiveWebAssembly ``` :::moniker-end diff --git a/aspnetcore/blazor/components/cascading-values-and-parameters.md b/aspnetcore/blazor/components/cascading-values-and-parameters.md index 33bb0e155e26..371f5e76c8c7 100644 --- a/aspnetcore/blazor/components/cascading-values-and-parameters.md +++ b/aspnetcore/blazor/components/cascading-values-and-parameters.md @@ -55,7 +55,7 @@ The following `Daleks` component displays the cascaded values. ```razor @page "/daleks" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer

Root-level cascading value registration example

@@ -154,7 +154,7 @@ Wrap the markup of the `Routes` component in a [`CascadingValue`](xref:Microsoft In the `App` component (`Components/App.razor`), adopt an interactive render mode for the entire app. The following example adopts Interactive Server rendering: ```razor - + ``` > [!NOTE] @@ -217,7 +217,7 @@ The following component binds the `ThemeInfo` cascading value to a cascading par ```razor @page "/themed-counter" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @using BlazorSample.UIThemeClasses

Themed Counter

diff --git a/aspnetcore/blazor/components/index.md b/aspnetcore/blazor/components/index.md index cbbc4e53c2e9..db6b93e25fbf 100644 --- a/aspnetcore/blazor/components/index.md +++ b/aspnetcore/blazor/components/index.md @@ -1436,9 +1436,9 @@ Whitespace isn't preserved from the preceding markup: :::moniker range=">= aspnetcore-6.0" -## Render static root Razor components +## Root component -A *root Razor component* is the first component loaded of any component hierarchy created by the app. +A *root Razor component* (*root component*) is the first component loaded of any component hierarchy created by the app. :::moniker-end @@ -1450,6 +1450,9 @@ In an app created from the Blazor Web App project template, the `App` component app.MapRazorComponents(); ``` +> [!NOTE] +> Making a root component interactive, such as the `App` component, isn't supported because the Blazor script may be evaluated multiple times. + :::moniker-end :::moniker range=">= aspnetcore-6.0 < aspnetcore-8.0" diff --git a/aspnetcore/blazor/components/integration.md b/aspnetcore/blazor/components/integration.md index 14082ff3981b..ed3b21abdc4b 100644 --- a/aspnetcore/blazor/components/integration.md +++ b/aspnetcore/blazor/components/integration.md @@ -81,7 +81,7 @@ You can supply a default layout with the . -Add an `App` component to the app, which serves as the root component for other components. +Add an `App` component to the app, which serves as the root component, which is the first component the app loads. `Components/App.razor`: @@ -154,7 +154,7 @@ In the ASP.NET Core project's `Program` file: app.UseAntiforgery(); ``` -* Add `MapRazorComponents` to the app's request processing pipeline with the `App` component (`App.razor`) specified as the default root component. Place the following code before the the line that calls `app.Run`: +* Add `MapRazorComponents` to the app's request processing pipeline with the `App` component (`App.razor`) specified as the default root component (the first component loaded). Place the following code before the the line that calls `app.Run`: ```csharp app.MapRazorComponents(); @@ -188,7 +188,7 @@ Add the following `Counter` component to the app that adopts the Interactive Ser ```razor @page "/counter" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer Counter @@ -225,15 +225,13 @@ Add a package reference for the [`Microsoft.AspNetCore.Components.WebAssembly.Se [!INCLUDE[](~/includes/package-reference.md)] - - Create a donor Blazor Web App to provide assets to the app. Follow the guidance in the article, selecting support for the following template features when generating the Blazor Web App. For the app's name, use the same name as the ASP.NET Core app, which results in matching app name markup in components and matching namespaces in code. Using the same name/namespace isn't strictly required, as namespaces can be adjusted after assets are moved from the donor app to the ASP.NET Core app. However, time is saved by matching the namespaces at the outset. Visual Studio: -* For **Interactivity type**, select **Auto (Server and WebAssembly)**. +* For **Interactive render mode**, select **Auto (Server and WebAssembly)**. * Set the **Interactivity location** to **Per page/component**. * Deselect the checkbox for **Include sample pages**. @@ -432,7 +430,7 @@ builder.Services.AddRazorComponents() For more information on adding support for Interactive Server and WebAssembly components, see . -In the `Program` file immediately after the call to map Razor Pages (), call to discover available components and specify the app's root component. By default, the app's root component is the `App` component (`App.razor`). Chain a call to `AddInteractiveInteractiveServerRenderMode` to configure the Server render mode for the app: +In the `Program` file immediately after the call to map Razor Pages (), call to discover available components and specify the app's root component (the first component loaded). By default, the app's root component is the `App` component (`App.razor`). Chain a call to `AddInteractiveInteractiveServerRenderMode` to configure the Server render mode for the app: ```csharp app.MapRazorComponents() @@ -777,7 +775,7 @@ Create a `Pages` folder in the `Components` folder for routable components. The ```razor @page "/counter" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer Counter diff --git a/aspnetcore/blazor/components/prerender.md b/aspnetcore/blazor/components/prerender.md index 957c034c99f6..c7a3ed1e909d 100644 --- a/aspnetcore/blazor/components/prerender.md +++ b/aspnetcore/blazor/components/prerender.md @@ -22,8 +22,8 @@ uid: blazor/components/prerender --> This article explains Razor component prerendering scenarios for server-rendered components in Blazor Web Apps. - -Prerendering can improve [Search Engine Optimization (SEO)](https://developer.mozilla.org/docs/Glossary/SEO) by rendering content for the initial HTTP response that search engines can use to calculate page rank. + +*Prerendering* is the process of initially rendering page content on the server without enabling event handlers for rendered controls. The server outputs the HTML UI of the page as soon as possible in response to the initial request, which makes the app feel more responsive to users. Prerendering can also improve [Search Engine Optimization (SEO)](https://developer.mozilla.org/docs/Glossary/SEO) by rendering content for the initial HTTP response that search engines use to calculate page rank. ## Persist prerendered state @@ -35,7 +35,7 @@ Consider the following `PrerenderedCounter1` counter component. The component se ```razor @page "/prerendered-counter-1" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject ILogger Logger Prerendered Counter 1 @@ -127,7 +127,7 @@ The following counter component example persists counter state during prerenderi ```razor @page "/prerendered-counter-2" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @implements IDisposable @inject ILogger Logger @inject PersistentComponentState ApplicationState diff --git a/aspnetcore/blazor/components/quickgrid.md b/aspnetcore/blazor/components/quickgrid.md index 72c76f834b9b..7c4772c27481 100644 --- a/aspnetcore/blazor/components/quickgrid.md +++ b/aspnetcore/blazor/components/quickgrid.md @@ -16,9 +16,7 @@ The `QuickGrid` component is a Razor component for quickly and efficiently displ ## Package - - -Add a ***prerelease*** package reference for the [`Microsoft.AspNetCore.Components.QuickGrid`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.QuickGrid) package. If using the .NET CLI to add the package reference, include the `--prerelease` option when you execute the [`dotnet add package` command](/dotnet/core/tools/dotnet-add-package). +Add a package reference for the [`Microsoft.AspNetCore.Components.QuickGrid`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.QuickGrid) package. [!INCLUDE[](~/includes/package-reference.md)] @@ -55,7 +53,7 @@ For example, add the following component to render a grid. ```razor @page "/quickgrid-example" @using Microsoft.AspNetCore.Components.QuickGrid -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @@ -78,7 +76,7 @@ For example, add the following component to render a grid. } ``` -The preceding example specifies server rendering (`@rendermode RenderMode.InteractiveServer`), which enables the `QuickGrid`'s interactive features. In this case, the only interactive feature is sortable columns. +The preceding example specifies server rendering (`@rendermode InteractiveServer`), which enables the `QuickGrid`'s interactive features. In this case, the only interactive feature is sortable columns. For an example that uses an with Entity Framework Core as the queryable data source, see the [`SampleQuickGridComponent` component in the ASP.NET Core Basic Test App (`dotnet/aspnetcore` GitHub repository)](https://github.com/dotnet/aspnetcore/blob/main/src/Components/test/testassets/BasicTestApp/QuickGridTest/SampleQuickGridComponent.razor). @@ -115,7 +113,7 @@ Add a ***prerelease*** package reference for the [`Microsoft.AspNetCore.Componen [!INCLUDE[](~/includes/package-reference.md)] > [!NOTE] -> Because the `Microsoft.AspNetCore.Components.QuickGrid` package is an experimental package for .NET 7, the package remains in *prerelease* status forever for .NET 7 Blazor apps. The package reached production status for .NET 8. For more information, see an 8.0 or later version of this article. +> Because the `Microsoft.AspNetCore.Components.QuickGrid` package is an experimental package for .NET 7, the package remains in *prerelease* status forever for .NET 7 Blazor apps. The package reached production status for .NET 8 or later. For more information, see an 8.0 or later version of this article. Add the following component to render a grid. diff --git a/aspnetcore/blazor/components/render-components-outside-of-aspnetcore.md b/aspnetcore/blazor/components/render-components-outside-of-aspnetcore.md index bd716e6d265d..59319a37399e 100644 --- a/aspnetcore/blazor/components/render-components-outside-of-aspnetcore.md +++ b/aspnetcore/blazor/components/render-components-outside-of-aspnetcore.md @@ -29,11 +29,9 @@ cd ConsoleApp1 In a command shell in the `ConsoleApp1` folder, add package references for and to the console app: - - ```dotnetcli -dotnet add package Microsoft.AspNetCore.Components.Web --prerelease -dotnet add package Microsoft.Extensions.Logging --prerelease +dotnet add package Microsoft.AspNetCore.Components.Web +dotnet add package Microsoft.Extensions.Logging ``` In the console app's project file (`ConsoleApp1.csproj`), update the console app project to use the Razor SDK: diff --git a/aspnetcore/blazor/components/render-modes.md b/aspnetcore/blazor/components/render-modes.md index ee421d69b7d9..5b8ef93457aa 100644 --- a/aspnetcore/blazor/components/render-modes.md +++ b/aspnetcore/blazor/components/render-modes.md @@ -18,6 +18,9 @@ uid: blazor/components/render-modes This article explains control of Razor component rendering in Blazor Web Apps, either at compile time or runtime. +> [!NOTE] +> This guidance doesn't apply to standalone Blazor WebAssembly apps. + ## Render modes Every component in a Blazor Web App adopts a *render mode* to determine the hosting model that it uses, where it's rendered, and whether or not it's interactive. @@ -31,7 +34,7 @@ Interactive Server | Interactive server rendering using Blazor Server | Server | Interactive WebAssembly | Interactive client rendering using Blazor WebAssembly | Client | Yes Interactive Auto | Interactive client rendering using Blazor Server initially and then WebAssembly on subsequent visits after the Blazor bundle is downloaded | Server, then client | Yes -Prerendering is enabled by default for interactive components. Guidance on controlling prerendering is provided later in this article. +Prerendering is enabled by default for interactive components. Guidance on controlling prerendering is provided later in this article. The following examples demonstrate setting the component's render mode with a few basic Razor component features. @@ -48,7 +51,7 @@ Component builder extensions: * `AddInteractiveServerComponents` adds services to support rendering Interactive Server components. * `AddInteractiveWebAssemblyComponents` adds services to support rendering Interactive WebAssembly components. - discovers available components and specifies the root component for the app, which by default is the `App` component (`App.razor`). + discovers available components and specifies the root component for the app (the first component loaded), which by default is the `App` component (`App.razor`). Endpoint convention builder extensions: @@ -105,46 +108,23 @@ To apply a render mode to a component instance use the [`@rendermode` Razor dire In the following example, the Server render mode is applied to the `Dialog` component instance: ```razor - + ``` - - > [!NOTE] -> For the release of .NET 8 in November, the Blazor templates will include a `using static` statement for in the app's `_Imports` file for shorter `@rendermode` syntax. -> -> In `Components/_Imports.razor`: +> Blazor templates include a static `using` directive for in the app's `_Imports` file (`Components/_Imports.razor`) for shorter `@rendermode` syntax: > > ```razor > @using static Microsoft.AspNetCore.Components.Web.RenderMode > ``` > -> Simplified `@rendermode` assignment: +> Without the preceding directive, components must specify the static class in `@rendermode` syntax: > > ```razor -> +> > ``` -> -> During *Release Candidate 2*, you can add the `using static` statement to your Blazor apps to shorten the syntax. - -You can reference static render mode instances instantiated directly with custom configuration: -```razor -@rendermode renderMode - -... - -@code { - private static IComponentRenderMode renderMode = - new InteractiveWebAssemblyRenderMode(prerender: false); -} -``` +You can also reference static render mode instances instantiated directly with custom configuration. For more information, see the [Custom shorthand render modes](#custom-shorthand-render-modes) section later in this article. ## Apply a render mode to a component definition @@ -152,18 +132,9 @@ To specify the render mode for a component as part of its definition, use the [` ```razor @page "..." -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer ``` - - -> [!NOTE] -> In an app generated from the Blazor project template during *Release Candidate 2*, add a `using static` statement for to `Components/_Imports.razor` if you want to use shortened syntax (`@rendermode InteractiveServer`): -> -> ```razor -> @using static Microsoft.AspNetCore.Components.Web.RenderMode -> ``` - Applying a render mode to a component definition is commonly used when applying a render mode to a specific page. Routable pages by default use the same render mode as the router component that rendered the page. Technically, `@rendermode` is both a Razor *directive* and a Razor *directive attribute*. The semantics are similar, but there are differences. The `@rendermode` directive is on the component definition, so the referenced render mode instance must be static. The `@rendermode` directive attribute can take any render mode instance. @@ -171,44 +142,32 @@ Technically, `@rendermode` is both a Razor *directive* and a Razor *directive at > [!NOTE] > Component authors should avoid coupling a component's implementation to a specific render mode. Instead, component authors should typically design components to support any render mode or hosting model. A component's implementation should avoid assumptions on where it's running (server or client) and should degrade gracefully when rendered statically. Specifying the render mode in the component definition may be needed if the component isn't instantiated directly (such as with a routable page component) or to specify a render mode for all component instances. -> [!NOTE] -> During .NET 8 *Release Candidate 2*, the Blazor Web App project template sets the interactive render mode with the [`@attribute` Razor directive](xref:mvc/views/razor#attribute) in template-generated sample components. The template will be updated to use the [`@rendermode` Razor directive](xref:mvc/views/razor#rendermode) for the release of .NET 8 in November. -> -> Render mode | Directive -> ----------------------- | --------- -> Interactive Server | `@attribute [RenderModeInteractiveServer]` -> Interactive WebAssembly | `@attribute [RenderModeInteractiveWebAssembly]` -> Interactive Auto | `@attribute [RenderModeInteractiveAuto]` -> -> You can change the directives in an app generated by the project template to use the `@rendermode` directive. - ## Prerendering +*Prerendering* is the process of initially rendering page content on the server without enabling event handlers for rendered controls. The server outputs the HTML UI of the page as soon as possible in response to the initial request, which makes the app feel more responsive to users. Prerendering can also improve [Search Engine Optimization (SEO)](https://developer.mozilla.org/docs/Glossary/SEO) by rendering content for the initial HTTP response that search engines use to calculate page rank. + Prerendering is enabled by default for interactive components. -To disable prerendering for a component instance, pass the `prerender` flag with a value of `false` with either a new `InteractiveServerRenderMode` or `InteractiveAutoRenderMode`: + -```razor -<... @rendermode="new InteractiveServerRenderMode(prerender: false)" /> -``` +To disable prerendering for a *component instance*, pass the `prerender` flag with a value of `false` to the render mode: -```razor -<... @rendermode="new InteractiveAutoRenderMode(prerender: false)" /> -``` +* `<... @rendermode="new InteractiveServerRenderMode(prerender: false)" />` +* `<... @rendermode="new InteractiveWebAssemblyRenderMode(prerender: false)" />` +* `<... @rendermode="new InteractiveAutoRenderMode(prerender: false)" />` -To disable prerendering in a component definition, pass the `prerender` flag with a value of `false` with either the `RenderModeInteractiveServer` attribute or `RenderModeInteractiveAuto` attribute: +To disable prerendering in a *component definition*: -```razor -@page "..." -@attribute [RenderModeInteractiveServer(prerender: false)] -``` +* `@rendermode @(new InteractiveServerRenderMode(prerender: false))` +* `@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false))` +* `@rendermode @(new InteractiveAutoRenderMode(prerender: false))` -```razor -@page "..." -@attribute [RenderModeInteractiveAuto(prerender: false)] -``` +To disable prerendering for the entire app, indicate the render mode at the highest-level interactive component in the app's component hierarchy that isn't a root component. + +> [!NOTE] +> Making a root component interactive, such as the `App` component, isn't supported because the Blazor script may be evaluated multiple times. Therefore, prerendering can't be disabled directly by the `App` component. -To disable prerendering for the entire app, indicate the render mode at the highest-level component in the app's component hierarchy that isn't a root component (root components can't be interactive). Typically, this is where the `Routes` component is used in the `App` component (`Components/App.razor`) for apps based on the Blazor Web App project template: +For apps based on the Blazor Web App project template, a render mode assigned to the entire app is specified where the `Routes` component is used in the `App` component (`Components/App.razor`). The following example sets the app's render mode to Interactive Server with prerendering disabled: ```razor @@ -251,13 +210,13 @@ If using the preceding component locally in a Blazor Web App, place the componen The Server render mode renders the component interactively from the server using Blazor Server. User interactions are handled over a real-time connection with the browser. The circuit connection is established when the Server component is rendered. -In the following example, the render mode is set to Server by adding `@rendermode RenderMode.InteractiveServer` to the component definition. The button calls the `UpdateMessage` method when selected. The value of `message` changes, and the component is rerendered to update the message in the UI. +In the following example, the render mode is set to Server by adding `@rendermode InteractiveServer` to the component definition. The button calls the `UpdateMessage` method when selected. The value of `message` changes, and the component is rerendered to update the message in the UI. `RenderMode2.razor`: ```razor @page "/render-mode-2" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @message @@ -277,13 +236,13 @@ If using the preceding component locally in a Blazor Web App, place the componen The WebAssembly render mode renders the component interactively on the client using Blazor WebAssembly. The .NET runtime and app bundle are downloaded and cached when the WebAssembly component is initially rendered. Components using the WebAssembly render mode must be built from a separate client project that sets up the Blazor WebAssembly host. -In the following example, the render mode is set to WebAssembly with `@rendermode RenderMode.InteractiveWebAssembly`. The button calls the `UpdateMessage` method when selected. The value of `message` changes, and the component is rerendered to update the message in the UI. +In the following example, the render mode is set to WebAssembly with `@rendermode InteractiveWebAssembly`. The button calls the `UpdateMessage` method when selected. The value of `message` changes, and the component is rerendered to update the message in the UI. `RenderMode3.razor`: ```razor @page "/render-mode-3" -@rendermode RenderMode.InteractiveWebAssembly +@rendermode InteractiveWebAssembly @message @@ -309,7 +268,7 @@ In the following example, the component is interactive throughout the process. T ```razor @page "/render-mode-4" -@rendermode RenderMode.InteractiveAuto +@rendermode InteractiveAuto @message @@ -383,7 +342,7 @@ In the following example, the `SharedMessage` component is interactive over a Si ```razor @page "/render-mode-6" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer ``` @@ -400,18 +359,10 @@ In the following example, both `SharedMessage` components are prerendered (by de ```razor @page "/render-mode-7" - - + + ``` -> [!NOTE] -> The preceding syntax will be simplified at the release of .NET 8 in November to: -> -> ```razor -> -> -> ``` - ### Child component with a serializable parameter The following example demonstrates an interactive child component that takes a parameter. Parameters must be serializable. @@ -421,16 +372,9 @@ The following example demonstrates an interactive child component that takes a p ```razor @page "/render-mode-8" - + ``` -> [!NOTE] -> The preceding syntax will be simplified at the release of .NET 8 in November to: -> -> ```razor -> -> ``` - Non-serializable component parameters, such as child content or a render fragment, are ***not*** supported. In the following example, passing child content to the `SharedMessage` component results in a runtime error. `RenderMode9.razor`: @@ -438,7 +382,7 @@ Non-serializable component parameters, such as child content or a render fragmen ```razor @page "/render-mode-9" - + Child content ``` @@ -462,16 +406,9 @@ To circumvent the preceding limitation, wrap the child component in another comp ```razor @page "/render-mode-10" - + ``` -> [!NOTE] -> The preceding syntax will be simplified at the release of .NET 8 in November to: -> -> ```razor -> -> ``` - In the preceding example: * The child content is passed to the `SharedMessage` component without generating a runtime error. @@ -487,9 +424,9 @@ The following component results in a runtime error when the component is rendere ```razor @page "/render-mode-11" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer - + ``` **Error**: @@ -498,38 +435,26 @@ The following component results in a runtime error when the component is rendere ## Set the render mode for the entire app -To set the render mode for the entire app, indicate the render mode at the highest-level component in the app's component hierarchy that isn't a root component (root components can't be interactive). Typically, this is where the `Routes` component is used in the `App` component (`Components/App.razor`) for apps based on the Blazor Web App project template: +To set the render mode for the entire app, indicate the render mode at the highest-level interactive component in the app's component hierarchy that isn't a root component. + +> [!NOTE] +> Making a root component interactive, such as the `App` component, isn't supported because the Blazor script may be evaluated multiple times. Therefore, the render mode for the entire app can't be set directly by the `App` component. + +For apps based on the Blazor Web App project template, a render mode assigned to the entire app is typically specified where the `Routes` component is used in the `App` component (`Components/App.razor`): ```razor - + ``` -> [!NOTE] -> The preceding syntax will be simplified at the release of .NET 8 in November to: -> -> ```razor -> -> ``` - The Blazor router propagates its render mode to the pages it routes. The pages aren't technically child components of the router, but when the routes are discovered at runtime for the router, they inherit the router's render mode. You also typically must set the same interactive render mode on the `HeadOutlet` component, which is also found in the `App` component of a Blazor Web App generated from the project template: ``` - + ``` -> [!NOTE] -> The preceding syntax will be simplified at the release of .NET 8 in November to: -> -> ```razor -> -> ``` - -> [!NOTE] -> Making a root component interactive, such as the `App` component, isn't supported because the Blazor script may be evaluated multiple times. - -To enable root-level interactivity when creating a Blazor Web App: +To enable global interactivity when creating a Blazor Web App: * Visual Studio: Set the **Interactivity location** dropdown list to **Global**. * .NET CLI: Use the `-ai|--all-interactive` option. @@ -555,27 +480,37 @@ app.MapRazorComponents() The `@rendermode` directive takes a single parameter that's a static instance of type . The `@rendermode` directive attribute can take any render mode instance, static or not. The Blazor framework provides the static class with some predefined render modes for convenience, but you can create your own. -Consider the following example that creates a shorthand Interactive Server render mode without prerendering: +Normally, a component uses the following `@attribute` directive to [disable prerendering](#prerendering): + +```razor +@attribute [RenderModeInteractiveServer(prerender: false)] +``` + +However, consider the following example that creates a shorthand Interactive Server render mode without prerendering via the app's `_Imports` file (`Components/_Imports.razor`): ```csharp public static IComponentRenderMode InteractiveServerWithoutPrerendering { get; } = new InteractiveServerRenderMode(prerender: false); ``` -Use the shorthand render mode in components: +Use the shorthand render mode in components throughout the `Components` folder: ```razor @rendermode InteractiveServerWithoutPrerendering ``` -> [!NOTE] -> Normally, a component uses the following `@attribute` directive to disable prerendering: -> -> ```razor -> @attribute [RenderModeInteractiveServer(prerender: false)] -> ``` -> -> For more information, see the [Prerendering](#prerendering) section. +Alternatively, a single component instance can define a custom render mode via a private field: + +```razor +@rendermode interactiveServerWithoutPrerendering + +... + +@code { + private static IComponentRenderMode interactiveServerWithoutPrerendering = + new InteractiveServerRenderMode(prerender: false); +} +``` At the moment, the shorthand render mode approach is probably only useful for reducing the verbosity of specifying the `prerender` flag. The shorthand approach might be more useful in the future if additional flags become available for interactive rendering and you would like to create shorthand render modes with different combinations of flags. diff --git a/aspnetcore/blazor/components/virtualization.md b/aspnetcore/blazor/components/virtualization.md index 1fdf38b8a692..220d1f788ce9 100644 --- a/aspnetcore/blazor/components/virtualization.md +++ b/aspnetcore/blazor/components/virtualization.md @@ -195,7 +195,7 @@ EmptyContent.razor: ```razor @page "/empty-content" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer

Empty Content Example

diff --git a/aspnetcore/blazor/debug.md b/aspnetcore/blazor/debug.md index cfa944a6ddd4..a8ae02faa13e 100644 --- a/aspnetcore/blazor/debug.md +++ b/aspnetcore/blazor/debug.md @@ -88,7 +88,7 @@ Unsupported scenarios for Blazor WebAssembly apps include: > [!NOTE] > Guidance in this article that focuses on using Visual Studio or Visual Studio Code only supports the latest release of the tooling. Confirm that you've updated your IDE to the latest released version. > -> For Visual Studio Code, the [C# Dev Kit for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit) ([Getting Started with C# in VS Code](https://code.visualstudio.com/docs/csharp/get-started)) is a preview product. The guidance in this article should work with the C# Dev Kit. If you encounter warnings or errors, you can [open an issue (microsoft/vscode-dotnettools GitHub repository)](https://github.com/microsoft/vscode-dotnettools/issues) describing the problem. +> For Visual Studio Code, the [C# Dev Kit for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit) is compatible with the guidance in this article. If you encounter warnings or errors, you can [open an issue (`microsoft/vscode-dotnettools` GitHub repository)](https://github.com/microsoft/vscode-dotnettools/issues) describing the problem. ## Prerequisites @@ -187,7 +187,7 @@ Breakpoints can also be hit in the server project. ```razor @page "/counter-2" - @rendermode RenderMode.InteractiveServer + @rendermode InteractiveServer Counter 2 @@ -227,13 +227,6 @@ Breakpoints are **not** hit during app startup before the debug proxy is running 1. In the browser, navigate to the `Counter2` page at `/counter-2`. Wait a few seconds for the debug proxy to load and run. Select the **Click me** button to hit the breakpoint. 1. Press F5 to continue execution. - - -> [!NOTE] -> During the .NET 8.0 *Release Candidate 1* preview, breakpoints placed anywhere in the server app of the solution aren't hit during debugging. This issue only applies to debugging with Visual Studio Code. This will be addressed in a future preview release or for the final release of .NET 8. - - - Breakpoints are **not** hit during app startup before the debug proxy is running. This includes breakpoints in the `Program` file and breakpoints in the [`OnInitialized{Async}` lifecycle methods](xref:blazor/components/lifecycle#component-initialization-oninitializedasync) of components that are loaded by the first page requested from the app. **Start Without Debugging** [Ctrl+F5 (Windows) or +F5 (macOS)] isn't supported. When the app is run in Debug configuration, debugging overhead always results in a small performance reduction. diff --git a/aspnetcore/blazor/file-downloads.md b/aspnetcore/blazor/file-downloads.md index 8559533d21c6..27f9b7788cbf 100644 --- a/aspnetcore/blazor/file-downloads.md +++ b/aspnetcore/blazor/file-downloads.md @@ -93,7 +93,7 @@ The following component: ```razor @page "/file-download-1" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @using System.IO @inject IJSRuntime JS @@ -202,7 +202,7 @@ Change the port in the following example to match the localhost development port ```razor @page "/file-download-2" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject IJSRuntime JS

File Download Example 2

diff --git a/aspnetcore/blazor/file-uploads.md b/aspnetcore/blazor/file-uploads.md index 09a99dd01192..02606c66e575 100644 --- a/aspnetcore/blazor/file-uploads.md +++ b/aspnetcore/blazor/file-uploads.md @@ -149,7 +149,7 @@ Because the example uses the app's [environment](xref:blazor/fundamentals/enviro ```razor @page "/file-upload-1" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject ILogger Logger @inject IHostEnvironment Environment @@ -282,7 +282,7 @@ The following example processes file bytes and doesn't send files to a destinati ```razor @page "/file-upload-1" -@rendermode RenderMode.InteractiveWebAssembly +@rendermode InteractiveWebAssembly @inject ILogger Logger

Upload Files

@@ -454,7 +454,7 @@ The following `FileUpload2` component: ```razor @page "/file-upload-2" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @using System.Net.Http.Headers @using System.Text.Json @inject IHttpClientFactory ClientFactory @@ -836,7 +836,7 @@ builder.Services.AddScoped(sp => Add the WebAssembly component rendering attribute to the top of the following component in a Blazor Web App: ```razor -@rendermode RenderMode.InteractiveWebAssembly +@rendermode InteractiveWebAssembly ``` :::moniker-end @@ -1174,7 +1174,7 @@ To use the following example in a test app: ```razor @page "/file-upload-3" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject ILogger Logger @inject IHostEnvironment Environment @@ -1364,7 +1364,7 @@ The following `FileUpload4` component shows the complete example. ```razor @page "/file-upload-4" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject IJSRuntime JS

File Upload Example

diff --git a/aspnetcore/blazor/forms/binding.md b/aspnetcore/blazor/forms/binding.md index 0548e559712d..3c83c6d255a5 100644 --- a/aspnetcore/blazor/forms/binding.md +++ b/aspnetcore/blazor/forms/binding.md @@ -236,7 +236,7 @@ The following example independently binds two forms to their models by form name ```razor @page "/starship-6" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject ILogger Logger @@ -337,7 +337,7 @@ The main form is bound to the `Ship` class. The `StarshipSubform` component is u ```razor @page "/starship-7" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject ILogger Logger diff --git a/aspnetcore/blazor/forms/index.md b/aspnetcore/blazor/forms/index.md index bafd30be487e..1abcc558bb3e 100644 --- a/aspnetcore/blazor/forms/index.md +++ b/aspnetcore/blazor/forms/index.md @@ -45,7 +45,7 @@ Standard interactive HTML forms with server rendering are supported. Create a fo ```razor @page "/starship-plain-form" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject ILogger Logger
@@ -108,7 +108,7 @@ A form is defined using the Blazor framework's Logger @@ -205,7 +205,7 @@ In the next example, the preceding component is modified to create the form in t ```razor @page "/starship-2" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject ILogger Logger @@ -290,7 +290,7 @@ For forms based on , the `A For forms based on the HTML `` element, manually add the `AntiforgeryToken` component to the form: ```razor -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @@ -378,8 +378,8 @@ For guidance on using the `enhancedload` event to listen for enhanced page updat Components are configured for interactivity with server rendering and enhanced navigation. For a client-side experience in a Blazor Web App, change the render mode in the `@rendermode` directive at the top of the component to either: -* `RenderMode.InteractiveWebAssembly` for only interactive client rendering after prerendering. -* `RenderMode.InteractiveAuto` for interactive client rendering after Interactive Server rendering, which operates while the Blazor app bundle downloads in the background and the .NET WebAssembly runtime starts on the client. +* `InteractiveWebAssembly` for only interactive client rendering after prerendering. +* `InteractiveAuto` for interactive client rendering after Interactive Server rendering, which operates while the Blazor app bundle downloads in the background and the .NET WebAssembly runtime starts on the client. If working with a standalone Blazor WebAssembly app, render modes aren't used. Blazor WebAssembly apps always run interactively on WebAssembly. The example interactive forms in this article function in a standalone Blazor WebAssembly app as long as the code doesn't make assumptions about running on the server instead of the client. You can remove the `@rendermode` directive from the component when using the example forms in a Blazor WebAssembly app. diff --git a/aspnetcore/blazor/forms/input-components.md b/aspnetcore/blazor/forms/input-components.md index e5635db8d7f9..096fd72afef7 100644 --- a/aspnetcore/blazor/forms/input-components.md +++ b/aspnetcore/blazor/forms/input-components.md @@ -125,7 +125,7 @@ The following form accepts and validates user input using: ```razor @page "/starship-3" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject ILogger Logger

Starfleet Starship Database

@@ -311,7 +311,7 @@ In the following example: ```razor @page "/starship-4" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject ILogger Logger @@ -452,7 +452,7 @@ In the following example, the user must select at least two starship classificat ```razor @page "/starship-5" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject ILogger Logger

Bind Multiple InputSelect Example

diff --git a/aspnetcore/blazor/forms/troubleshoot.md b/aspnetcore/blazor/forms/troubleshoot.md index 20694ee14fac..6987a390929b 100644 --- a/aspnetcore/blazor/forms/troubleshoot.md +++ b/aspnetcore/blazor/forms/troubleshoot.md @@ -51,7 +51,7 @@ Due to security considerations, zero-length streams aren't permitted for streami ```razor @page "/stream-form-data" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject IJSRuntime JS @inject ILogger Logger diff --git a/aspnetcore/blazor/forms/validation.md b/aspnetcore/blazor/forms/validation.md index 21bb7350e115..f36b7f1ee6ef 100644 --- a/aspnetcore/blazor/forms/validation.md +++ b/aspnetcore/blazor/forms/validation.md @@ -24,7 +24,7 @@ In the following component, the `HandleValidationRequested` handler method clear ```razor @page "/starship-8" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @implements IDisposable @inject ILogger Logger @@ -319,7 +319,7 @@ When validation messages are set in the component, they're added to the validato ```razor @page "/starship-9" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject ILogger Logger

Starfleet Starship Database

@@ -724,7 +724,7 @@ In the following component, update the namespace of the **`Shared`** project (`@ ```razor @page "/starship-10" -@rendermode RenderMode.InteractiveWebAssembly +@rendermode InteractiveWebAssembly @using System.Net @using System.Net.Http.Json @using Microsoft.AspNetCore.Authorization @@ -1038,7 +1038,7 @@ The `CustomInputText` component can be used anywhere Logger @@ -1249,7 +1249,7 @@ The following component validates user input by applying the `SaladChefValidator ```razor @page "/starship-12" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject SaladChef SaladChef @@ -1398,7 +1398,7 @@ Set the `CustomFieldClassProvider` class as the Field CSS Class Provider on the ```razor @page "/starship-13" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject ILogger Logger @@ -1766,7 +1766,7 @@ To enable and disable the submit button based on form validation, the following ```razor @page "/starship-14" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @implements IDisposable @inject ILogger Logger diff --git a/aspnetcore/blazor/fundamentals/dependency-injection.md b/aspnetcore/blazor/fundamentals/dependency-injection.md index 2479e4f124da..677feae2b02f 100644 --- a/aspnetcore/blazor/fundamentals/dependency-injection.md +++ b/aspnetcore/blazor/fundamentals/dependency-injection.md @@ -336,7 +336,7 @@ In the following `TimeTravel` component: ```razor @page "/time-travel" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject ITimeTravel TimeTravel1 @inherits OwningComponentBase @@ -411,7 +411,7 @@ In spite of the scoped service registration in the `Program` file and the longev ```razor @page "/users" @attribute [Authorize] -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inherits OwningComponentBase

Users (@Service.Users.Count())

diff --git a/aspnetcore/blazor/fundamentals/handle-errors.md b/aspnetcore/blazor/fundamentals/handle-errors.md index ed3a8dc28e88..7c92f5e98765 100644 --- a/aspnetcore/blazor/fundamentals/handle-errors.md +++ b/aspnetcore/blazor/fundamentals/handle-errors.md @@ -390,7 +390,7 @@ In `MainLayout.razor`: In Blazor Web Apps with the error boundary only applied to a noninteractive `MainLayout` component, the boundary is only active during the Static Server rendering phase. The boundary doesn't activate just because a component further down the component hierarchy is interactive. To enable interactivity broadly for the `MainLayout` component and the rest of the components further down the component hierarchy, enable interactivity with server rendering at the top of the `Routes` component (`Components/Routes.razor`): ```razor -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer ``` If you prefer not to enable server interactivity across the entire app from the `Routes` component, place the error boundary further down the component hierarchy. For example, place the error boundary around markup in individual components that enable interactivity, not in the app's main layout. The important concepts to keep in mind are that wherever the error boundary is placed: diff --git a/aspnetcore/blazor/fundamentals/index.md b/aspnetcore/blazor/fundamentals/index.md index f0698c9275fc..1ef71b1d3d05 100644 --- a/aspnetcore/blazor/fundamentals/index.md +++ b/aspnetcore/blazor/fundamentals/index.md @@ -14,6 +14,32 @@ uid: blazor/fundamentals/index *Fundamentals* articles provide guidance on foundational Blazor concepts. Some of the concepts are connected to a basic understanding of *Razor components*, which are described further in the next section of this article and covered in detail in the *Components* articles. +## Client and server rendering concepts + +Throughout the Blazor documentation, activity that takes place on the user's system is said to occur *on the client* or *client-side*. Activity that takes place on a server is said to occur *on the server* or *server-side*. + +The term *rendering* means to produce the HTML markup that browsers display. + +*Client-side rendering* means that the final HTML markup is generated by the Blazor WebAssembly runtime on the client. No HTML for the app's client-generated UI is sent from a server to the client for this type of rendering. + +*Server-side rendering* means that the final HTML markup is generated by the ASP.NET Core runtime on the server. The HTML is sent to the client over a network for display by the client's browser. No HTML for the app's server-generated UI is created by the client for this type of rendering. + +*Prerendering* is the process of initially rendering page content on the server without enabling event handlers for rendered controls. The server outputs the HTML UI of the page as soon as possible in response to the initial request, which makes the app feel more responsive to users. Prerendering can also improve [Search Engine Optimization (SEO)](https://developer.mozilla.org/docs/Glossary/SEO) by rendering content for the initial HTTP response that search engines use to calculate page rank. Prerendering is always followed by final rendering, either on the server or the client. + +:::moniker range=">= aspnetcore-8.0" + +## Static and interactive rendering concepts + +Razor components are either *statically* rendered or *interactively* rendered. + +*Static* or *static rendering* is a server-side scenario that means the component is rendered without the capacity for interplay between the user and .NET/C# code. JavaScript and HTML DOM events remain unaffected, but no user events on the client can be processed with .NET running on the server. + +*Interactive* or *interactive rendering* means that the component has the capacity to process .NET events via C# code. The .NET events are either processed on the server by the ASP.NET Core runtime or in the browser on the client by the WebAssembly-based Blazor runtime. + +More information on these concepts and how to control static and interactive rendering is found in the article later in the Blazor documentation. + +:::moniker-end + ## Razor components Blazor apps are based on *Razor components*, often referred to as just *components*. A *component* is an element of UI, such as a page, dialog, or data entry form. Components are .NET C# classes built into [.NET assemblies](/dotnet/standard/assembly/). @@ -38,7 +64,33 @@ The following is an example counter component and part of an app created from a `Counter.razor`: -:::moniker range=">= aspnetcore-7.0" +:::moniker range=">= aspnetcore-8.0" + +```razor +@page "/counter" +@rendermode InteractiveServer + +Counter + +

Counter

+ +

Current count: @currentCount

+ + + +@code { + private int currentCount = 0; + + private void IncrementCount() + { + currentCount++; + } +} +``` + +:::moniker-end + +:::moniker range=">= aspnetcore-7.0 < aspnetcore-8.0" :::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/Counter.razor"::: @@ -69,6 +121,31 @@ The preceding `Counter` component: * Renders the current count with `@currentCount`. `currentCount` is an integer variable defined in the C# code of the `@code` block. * Displays a button to trigger the `IncrementCount` method, which is also found in the `@code` block and increases the value of the `currentCount` variable. +:::moniker range=">= aspnetcore-8.0" + +## Render modes + +Articles in the *Fundamentals* node make reference to the concept of *render modes*. This subject is covered in detail in the article in the *Components* node, which appears after the *Fundamentals* node of articles. + +For the early references in this node of articles to render mode concepts, merely note the following at this time: + +Every component in a Blazor Web App adopts a *render mode* to determine the hosting model that it uses, where it's rendered, and whether or not it's rendered statically on the server, rendered with for user interactivity on the server, or rendered for user interactivity on the client (usually with prerendering on the server). + +Blazor Server and Blazor WebAssembly apps for ASP.NET Core releases prior to .NET 8 remain fixated on *hosting model* concepts, not render modes. Render modes are conceptually applied to Blazor Web Apps in .NET 8 or later. + +The following table shows the available render modes for rendering Razor components in a Blazor Web App. Render modes are applied to components with the `@rendermode` directive on the component instance or on the component definition. It's also possible to set a render mode for the entire app. + +Name | Description | Render location | Interactive +---- | ----------- | :-------------: | :---------: +Static | Static server rendering | Server | No +Interactive Server | Interactive server rendering using Blazor Server | Server | Yes +Interactive WebAssembly | Interactive client rendering using Blazor WebAssembly | Client | Yes +Interactive Auto | Interactive client rendering using Blazor Server initially and then WebAssembly on subsequent visits after the Blazor bundle is downloaded | Server, then client | Yes + +The preceding information on render modes is all that you need to know to understand the *Fundamentals* node articles. If you're new to Blazor and reading Blazor articles in order down the table of contents, you can delay consuming in-depth information on render modes until you reach the article in the *Components* node. + +:::moniker-end + ## Document Object Model (DOM) References to the *Document Object Model* use the abbreviation *DOM*. diff --git a/aspnetcore/blazor/fundamentals/logging.md b/aspnetcore/blazor/fundamentals/logging.md index eec07912ae88..20cb249d9783 100644 --- a/aspnetcore/blazor/fundamentals/logging.md +++ b/aspnetcore/blazor/fundamentals/logging.md @@ -495,7 +495,7 @@ In the following `CustomLoggerExample` component: ```razor @page "/custom-logger-example" -@rendermode RenderMode.InteractiveWebAssembly +@rendermode InteractiveWebAssembly @using Microsoft.Extensions.Logging @inject ILogger Logger diff --git a/aspnetcore/blazor/fundamentals/routing.md b/aspnetcore/blazor/fundamentals/routing.md index c25b6dd32510..e85ee0a08d82 100644 --- a/aspnetcore/blazor/fundamentals/routing.md +++ b/aspnetcore/blazor/fundamentals/routing.md @@ -327,6 +327,8 @@ Route constraints also work with [optional parameters](#route-parameters). In th :::moniker-end +:::moniker range="< aspnetcore-8.0" + ## Routing with URLs that contain dots A ***server-side*** default route template assumes that if the last segment of a request URL contains a dot (`.`) that a file is requested. For example, the relative URL `/example/some.thing` is interpreted by the router as a request for a file named `some.thing`. Without additional configuration, an app returns a *404 - Not Found* response if `some.thing` was meant to route to a component with an [`@page`](xref:mvc/views/razor#page) directive and `some.thing` is a route parameter value. To use a route with one or more parameters that contain a dot, the app must configure the route with a custom template. @@ -335,9 +337,9 @@ Consider the following `Example` component that can receive a route parameter fr `Example.razor`: - +:::moniker-end -:::moniker range=">= aspnetcore-7.0" +:::moniker range=">= aspnetcore-7.0 < aspnetcore-8.0" :::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_Server/Pages/routing/Example.razor" highlight="1"::: @@ -361,19 +363,6 @@ Consider the following `Example` component that can receive a route parameter fr :::moniker-end -:::moniker range=">= aspnetcore-8.0" - - - -For server-side configuration that routes requests with a dot in the `param` route parameter, add a fallback page route template with the optional parameter in the `Program` file: - -```csharp -app.MapFallbackToPage("/example/{param?}", "/"); -``` - -:::moniker-end - :::moniker range=">= aspnetcore-6.0 < aspnetcore-8.0" To permit the **:::no-loc text="Server":::** app of a hosted Blazor WebAssembly [solution](xref:blazor/tooling#visual-studio-solution-file-sln) to route the request with a dot in the `param` route parameter, add a fallback file route template with the optional parameter in the `Program` file: @@ -388,6 +377,8 @@ To configure a Blazor Server app to route the request with a dot in the `param` app.MapFallbackToPage("/example/{param?}", "/_Host"); ``` +For more information, see . + :::moniker-end :::moniker range="< aspnetcore-6.0" @@ -408,10 +399,10 @@ To configure a Blazor Server app to route the request with a dot in the `param` endpoints.MapFallbackToPage("/example/{param?}", "/_Host"); ``` -:::moniker-end - For more information, see . +:::moniker-end + :::moniker range=">= aspnetcore-5.0" ## Catch-all route parameters @@ -1556,7 +1547,7 @@ The following HTML markup is rendered: :::moniker range=">= aspnetcore-8.0" -A Blazor Web App is integrated into [ASP.NET Core Endpoint Routing](xref:fundamentals/routing). An ASP.NET Core app is configured to accept incoming connections for interactive components with in the `Program` file. The default root component is the `App` component (`App.razor`): +A Blazor Web App is integrated into [ASP.NET Core Endpoint Routing](xref:fundamentals/routing). An ASP.NET Core app is configured to accept incoming connections for interactive components with in the `Program` file. The default root component (first component loaded) is the `App` component (`App.razor`): ```csharp app.MapRazorComponents(); @@ -1588,9 +1579,6 @@ Blazor Server is integrated into [ASP.NET Core Endpoint Routing](xref:fundamenta :::moniker range="< aspnetcore-8.0" - - The typical configuration is to route all requests to a Razor page, which acts as the host for the server-side part of the Blazor Server app. By convention, the *host* page is usually named `_Host.cshtml` in the `Pages` folder of the app. The route specified in the host file is called a *fallback route* because it operates with a low priority in route matching. The fallback route is used when other routes don't match. This allows the app to use other controllers and pages without interfering with component routing in the Blazor Server app. diff --git a/aspnetcore/blazor/fundamentals/startup.md b/aspnetcore/blazor/fundamentals/startup.md index 2c2f708fa2e6..e9b780de0e54 100644 --- a/aspnetcore/blazor/fundamentals/startup.md +++ b/aspnetcore/blazor/fundamentals/startup.md @@ -102,17 +102,10 @@ JS initializers are detected as part of the build process and imported automatic To define a JS initializer, add a JS module to the project named `{NAME}.lib.module.js`, where the `{NAME}` placeholder is the assembly name, library name, or package identifier. Place the file in the project's web root, which is typically the `wwwroot` folder. -The module exports either or both of the following conventional functions: - :::moniker-end :::moniker range=">= aspnetcore-8.0" - - -> [!NOTE] -> JS initializers for Blazor Web Apps is an upcoming feature that will appear with the release of .NET 8 in mid-November. - For Blazor Web Apps: * `beforeWebStart(options)`: Called before the Blazor Web App starts. For example, `beforeWebStart` is used to customize the loading process, logging level, and other options. Receives the Blazor Web options (`options`). @@ -152,11 +145,6 @@ For the file name: :::moniker range=">= aspnetcore-8.0" - - -> [!NOTE] -> JS initializers for Blazor Web Apps is an upcoming feature that will appear with the release of .NET 8 in mid-November. - For Blazor Web Apps: The following example demonstrates JS initializers that load custom scripts before and after the Blazor Web App has started by appending them to the `` in `beforeWebStart` and `afterWebStarted`: diff --git a/aspnetcore/blazor/globalization-localization.md b/aspnetcore/blazor/globalization-localization.md index 5f96de112ef2..8570d211d3be 100644 --- a/aspnetcore/blazor/globalization-localization.md +++ b/aspnetcore/blazor/globalization-localization.md @@ -77,7 +77,9 @@ For current browser support of the preceding types, see [Can I use](https://cani Blazor WebAssembly uses a reduced globalization API and set of built-in International Components for Unicode (ICU) locales. For more information, see [.NET globalization and ICU: ICU on WebAssembly](/dotnet/core/extensions/globalization-icu#icu-on-webassembly). -To load a custom ICU data file to control the app's locales, see [WASM Globalization Icu](https://github.com/dotnet/runtime/blob/main/docs/design/features/globalization-icu-wasm.md). Currently, manually building the custom ICU data file is required. .NET tooling to ease the process of creating the file is planned for a future .NET 8.0 preview release. + + +To load a custom ICU data file to control the app's locales, see [WASM Globalization Icu](https://github.com/dotnet/runtime/blob/main/docs/design/features/globalization-icu-wasm.md). Currently, manually building the custom ICU data file is required. .NET tooling to ease the process of creating the file is planned for .NET 9 in November, 2024. :::moniker-end diff --git a/aspnetcore/blazor/host-and-deploy/webassembly.md b/aspnetcore/blazor/host-and-deploy/webassembly.md index 724e465faef6..6d9da0346349 100644 --- a/aspnetcore/blazor/host-and-deploy/webassembly.md +++ b/aspnetcore/blazor/host-and-deploy/webassembly.md @@ -1337,16 +1337,10 @@ If a deployed app frequently displays the reconnection UI due to ping timeouts c > [!IMPORTANT] > The Keep-Alive interval () isn't directly related to the reconnection UI appearing. The Keep-Alive interval doesn't necessarily need to be changed. If the reconnection UI appearance issue is due to timeouts, the server timeout can be increased and the Keep-Alive interval can remain the same. The important consideration is that if you change the Keep-Alive interval, make sure that the timeout value is at least double the value of the Keep-Alive interval and that the Keep-Alive interval on the server matches the client setting. - > - > In the following example, a custom value of 60 seconds is used for the server timeout. - When creating a hub connection in a component, set the (default: 30 seconds) and (default: 15 seconds). - - + When creating a hub connection in a component, you can customize the (default: 30 seconds) and (default: 15 seconds) values as necessary. - The following example is based on the `Index` component in the [SignalR with Blazor tutorial](xref:blazor/tutorials/signalr-blazor). The server timeout is increased to 60 seconds, and the handshake timeout is increased to 30 seconds: + In the following example, the server timeout is increased to 60 seconds, and the handshake timeout is increased to 30 seconds: :::moniker-end diff --git a/aspnetcore/blazor/hosting-models.md b/aspnetcore/blazor/hosting-models.md index 0e2bd6374f17..1612bc274a8b 100644 --- a/aspnetcore/blazor/hosting-models.md +++ b/aspnetcore/blazor/hosting-models.md @@ -20,7 +20,7 @@ NOTE: Daggered lines under the table (†, ‡) use a double-space at :::moniker range=">= aspnetcore-8.0" -This article explains Blazor hosting models, which can be applied in different parts of a Blazor app at either compile time or runtime. +This article explains Blazor hosting models, primarily focused on Blazor Server and Blazor WebAssembly apps in versions of .NET earlier than .NET 8. The guidance in this article is relevant under all .NET releases for Blazor Hybrid apps that run on native mobile and desktop platforms. Blazor Web Apps in .NET 8 or later are better conceptualized by how Razor components are rendered, which is described as their *render mode*. Render modes are briefly touched on in the *Fundamentals* overview article and covered in detail in of the *Components* node. :::moniker-end @@ -30,19 +30,7 @@ This article explains Blazor hosting models and how to choose which one to use. :::moniker-end -:::moniker range=">= aspnetcore-8.0" - -Blazor is a web framework for building web UI components ([Razor components](xref:blazor/components/index)) that can be hosted in different ways: - -* Server-side in ASP.NET Core (*Blazor Server* or statically rendered). -* Client-side in the browser on a [WebAssembly](https://webassembly.org/)-based .NET runtime (*Blazor WebAssembly*). -* Client-side in a native mobile or desktop app that renders components to an embedded Web View control (*Blazor Hybrid*). - -Regardless of the hosting model, the way you build Razor components *is the same*. The same Razor components can be used with any of the hosting models unchanged. - -:::moniker-end - -:::moniker range=">= aspnetcore-6.0 < aspnetcore-8.0" +:::moniker range=">= aspnetcore-6.0" Blazor is a web framework for building web UI components ([Razor components](xref:blazor/components/index)) that can be hosted in different ways. Razor components can run server-side in ASP.NET Core (*Blazor Server*) versus client-side in the browser on a [WebAssembly](https://webassembly.org/)-based .NET runtime (*Blazor WebAssembly*, *Blazor WASM*). You can also host Razor components in native mobile and desktop apps that render to an embedded Web View control (*Blazor Hybrid*). Regardless of the hosting model, the way you build Razor components *is the same*. The same Razor components can be used with any of the hosting models unchanged. diff --git a/aspnetcore/blazor/images.md b/aspnetcore/blazor/images.md index c30e441b6601..3dd0b27b1010 100644 --- a/aspnetcore/blazor/images.md +++ b/aspnetcore/blazor/images.md @@ -40,7 +40,7 @@ In the following `ShowImage1` component: ```razor @page "/show-image-1" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer

Dynamic Image Source Example

@@ -153,7 +153,7 @@ The following `ShowImage2` component: ```razor @page "/show-image-2" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject HttpClient Http @inject IJSRuntime JS diff --git a/aspnetcore/blazor/includes/location-client-and-server-net8-or-later.md b/aspnetcore/blazor/includes/location-client-and-server-net8-or-later.md index f64da3a270fb..aaba334cc31a 100644 --- a/aspnetcore/blazor/includes/location-client-and-server-net8-or-later.md +++ b/aspnetcore/blazor/includes/location-client-and-server-net8-or-later.md @@ -1,6 +1,6 @@ -Throughout this article, the terms **client**/**client-side** and **server**/**server-side** are used to distinguish locations where app code executes: +Throughout this article, the terms **server**/**server-side** and **client**/**client-side** are used to distinguish locations where app code executes: +* **Server**/**server-side**: Interactive Server rendering in a Blazor Web App. The `Program` file is `Program.cs` of the server project. Blazor script start configuration is found in the `App` component (`Components/App.razor`). Only routable Server render mode components with an `@page` directive are placed in the `Components/Pages` folder. Non-routable shared components are placed in the server project's `Components` folder. Create custom folders based on component functionality as needed. * **Client**/**client-side** - * Interactive client rendering of a Blazor Web App. The `Program` file is `Program.cs` of the client project (`.Client`). Blazor script start configuration is found in the `App` component (`Components/App.razor`) of the server project. Routable WebAssembly and Auto render mode components with an `@page` directive are placed in the client project's `Pages` folder. Place non-routable shared components at the root of the `.Client` project or in custom folders based on component functionality. + * Interactive WebAssembly rendering in a Blazor Web App. The `Program` file is `Program.cs` of the client project (`.Client`). Blazor script start configuration is found in the `App` component (`Components/App.razor`) of the server project. Routable Interactive WebAssembly and Interactive Auto components with an `@page` directive are placed in the client project's `Pages` folder. Place non-routable shared components at the root of the `.Client` project or in custom folders based on component functionality. * A Blazor WebAssembly app. The `Program` file is `Program.cs`. Blazor script start configuration is found in the `wwwroot/index.html` file. -* **Server**/**server-side**: Interactive server rendering of a Blazor Web App. The `Program` file is `Program.cs` of the server project. Blazor script start configuration is found in the `App` component (`Components/App.razor`). Only routable Server render mode components with an `@page` directive are placed in the `Components/Pages` folder. Non-routable shared components are placed in the server project's `Components` folder. Create custom folders based on component functionality as needed. diff --git a/aspnetcore/blazor/includes/location-client.md b/aspnetcore/blazor/includes/location-client.md index bde4655a38d8..637787a5f6ec 100644 --- a/aspnetcore/blazor/includes/location-client.md +++ b/aspnetcore/blazor/includes/location-client.md @@ -2,7 +2,7 @@ This guidance applies to: :::moniker range=">= aspnetcore-8.0" -* Interactive client rendering of a Blazor Web App. The `Program` file is `Program.cs` of the client project (`.Client`). Blazor script start configuration is found in the `App` component (`Components/App.razor`) of the server project. Routable WebAssembly and Auto render mode components with an `@page` directive are placed in the client project's `Pages` folder. Place non-routable shared components at the root of the `.Client` project or in custom folders based on component functionality. +* Interactive WebAssembly rendering in a Blazor Web App. The `Program` file is `Program.cs` of the client project (`.Client`). Blazor script start configuration is found in the `App` component (`Components/App.razor`) of the server project. Routable Interactive WebAssembly and Interactive Auto components with an `@page` directive are placed in the client project's `Pages` folder. Place non-routable shared components at the root of the `.Client` project or in custom folders based on component functionality. * A Blazor WebAssembly app. The `Program` file is `Program.cs`. Blazor script start configuration is found in the `wwwroot/index.html` file. :::moniker-end diff --git a/aspnetcore/blazor/includes/location-server.md b/aspnetcore/blazor/includes/location-server.md index 44742a5548b0..aa15ea4a7874 100644 --- a/aspnetcore/blazor/includes/location-server.md +++ b/aspnetcore/blazor/includes/location-server.md @@ -1,8 +1,8 @@ :::moniker range=">= aspnetcore-8.0" -This guidance applies to interactive components with server rendering of a Blazor Web App. The `Program` file is `Program.cs` of the server project. Blazor script start configuration is found in the `App` component (`Components/App.razor`). +This guidance applies to Interactive Server components of a Blazor Web App. The `Program` file is `Program.cs` of the server project. Blazor script start configuration is found in the `App` component (`Components/App.razor`). -Only routable Server render mode components with an `@page` directive are placed in the `Components/Pages` folder. Non-routable shared components are placed in the server project's `Components` folder. Create custom folders based on component functionality as needed. +Only routable Interactive Server components with an `@page` directive are placed in the `Components/Pages` folder. Non-routable shared components are placed in the server project's `Components` folder. Create custom folders based on component functionality as needed. :::moniker-end diff --git a/aspnetcore/blazor/index.md b/aspnetcore/blazor/index.md index 3032af89f0b6..578f57be0bee 100644 --- a/aspnetcore/blazor/index.md +++ b/aspnetcore/blazor/index.md @@ -96,9 +96,9 @@ Components render into an in-memory representation of the browser's [Document Ob Blazor Web Apps provide a component-based architecture with server-side rendering and full client-side interactivity in a single solution, where you can switch between server-side and client-side rendering modes and even mix them in the same page. -Blazor Web Apps can deliver UI to the browser fast by statically rendering HTML content from the server in response to requests. The page loads fast because UI rendering is performed quickly on the server without the need to download a large JavaScript bundle. Blazor can also further improve the user experience with various progressive enhancements to server rendering, such as enhanced navigation with form posts and streaming rendering of asynchronously-generated content. +Blazor Web Apps can quickly deliver UI to the browser by statically rendering HTML content from the server in response to requests. The page loads fast because UI rendering is performed quickly on the server without the need to download a large JavaScript bundle. Blazor can also further improve the user experience with various progressive enhancements to server rendering, such as enhanced navigation with form posts and streaming rendering of asynchronously-generated content. -Blazor supports *interactive* server rendering, where UI interactions are handled from the server over a real-time connection with the browser. Interactive server rendering enables a rich user experience like one would expect from a client app but without the need to create API endpoints to access server resources. +Blazor supports *interactive* server rendering, where UI interactions are handled from the server over a real-time connection with the browser. Interactive server rendering enables a rich user experience like one would expect from a client app but without the need to create API endpoints to access server resources. Page content for interactive pages is prerendered, where content on the server is initially generated and sent to the client without enabling event handlers for rendered controls. The server outputs the HTML UI of the page as soon as possible in response to the initial request, which makes the app feel more responsive to users. Blazor Web Apps support interactivity with client rendering that relies on a .NET runtime built with [WebAssembly](https://webassembly.org) that you can download with your app. When running Blazor on WebAssembly, your .NET code can access the full functionality of the browser and interop with JavaScript. Your .NET code runs in the browser's security sandbox with the protections that the sandbox provides against malicious actions on the client machine. @@ -132,7 +132,7 @@ Blazor Server apps render content differently than traditional models for render When a Razor Page or view is rendered, every line of Razor code emits HTML in text form. After rendering, the server disposes of the page or view instance, including any state that was produced. When another request for the page occurs, the entire page is rerendered to HTML again and sent to the client. -Blazor Server produces a graph of components to display similar to an HTML or XML DOM. The component graph includes state held in properties and fields. Blazor evaluates the component graph to produce a binary representation of the markup, which is sent to the client for rendering. After the connection is made between the client and the server, the component's static prerendered elements are replaced with interactive elements. Prerendering the content on the server makes the app feel more responsive on the client. +Blazor Server produces a graph of components to display similar to an HTML or XML DOM. The component graph includes state held in properties and fields. Blazor evaluates the component graph to produce a binary representation of the markup, which is sent to the client for rendering. After the connection is made between the client and the server, the component's static prerendered elements are replaced with interactive elements. Prerendering content on the server in order to load HTML content on the client quickly makes the app feel more responsive to the client. After the components are interactive on the client, UI updates are triggered by user interaction and app events. When an update occurs, the component graph is rerendered, and a UI *diff* (difference) is calculated. This diff is the smallest set of DOM edits required to update the UI on the client. The diff is sent to the client in a binary format and applied by the browser. diff --git a/aspnetcore/blazor/javascript-interoperability/call-dotnet-from-javascript.md b/aspnetcore/blazor/javascript-interoperability/call-dotnet-from-javascript.md index 91b26a5d9b50..ce955d159c8d 100644 --- a/aspnetcore/blazor/javascript-interoperability/call-dotnet-from-javascript.md +++ b/aspnetcore/blazor/javascript-interoperability/call-dotnet-from-javascript.md @@ -76,7 +76,7 @@ In the following `CallDotNetExample1` component, the `ReturnArrayAsync` C# metho ```razor @page "/call-dotnet-example-1" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer

Call .NET Example 1

@@ -364,7 +364,7 @@ For the following `CallDotNetExample2` component: ```razor @page "/call-dotnet-example-2" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @implements IDisposable @inject IJSRuntime JS @@ -461,7 +461,7 @@ Provide the parameter list to the .NET method. ```razor @page "/call-dotnet-example-3" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @implements IDisposable @inject IJSRuntime JS @@ -550,7 +550,7 @@ In the following `CallDotNetExampleOneHelper` component, the `Trigger JS functio ```razor @page "/call-dotnet-example-one-helper" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @implements IDisposable @inject IJSRuntime JS @@ -873,7 +873,7 @@ In the following `GenericsExample` component: ```razor @page "/generics-example" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @using System.Runtime.InteropServices @inject IJSRuntime JS @implements IDisposable @@ -1088,7 +1088,7 @@ When the **`Trigger .NET instance method`** button is selected in the following ```razor @page "/call-dotnet-example-4" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject IJSRuntime JS

Call .NET Example 4

@@ -1167,7 +1167,7 @@ The preceding pattern shown in the `JsInteropClasses3` class can also be impleme ```razor @page "/call-dotnet-example-5" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject IJSRuntime JS

Call .NET Example 5

@@ -1311,7 +1311,7 @@ When a `ListItem1` component's **`InteropCall`** button is selected, `updateMess :::moniker range=">= aspnetcore-8.0" ```razor -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject IJSRuntime JS
  • @@ -1488,7 +1488,7 @@ The is disposed when the compon :::moniker range=">= aspnetcore-8.0" ```razor -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject IJSRuntime JS
  • @@ -1705,7 +1705,7 @@ Provide a `sendByteArray` JS function. The function is called statically, which ```razor @page "/call-dotnet-example-8" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @using System.Text

    Call .NET Example 8

    diff --git a/aspnetcore/blazor/javascript-interoperability/call-javascript-from-dotnet.md b/aspnetcore/blazor/javascript-interoperability/call-javascript-from-dotnet.md index 5419ed80c0fd..7a7467596e92 100644 --- a/aspnetcore/blazor/javascript-interoperability/call-javascript-from-dotnet.md +++ b/aspnetcore/blazor/javascript-interoperability/call-javascript-from-dotnet.md @@ -63,7 +63,7 @@ The following `CallJsExample1` component: ```razor @page "/call-js-example-1" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject IJSRuntime JS

    Call JS convertArray Function

    @@ -163,7 +163,7 @@ Provide a `displayTickerAlert1` JS function. The function is called with Call JS Example 2 @@ -254,7 +254,7 @@ Provide a `displayTickerAlert1` JS function. The function is called with Call JS Example 4 @@ -453,7 +453,7 @@ Provide a `displayTickerAlert2` JS function. The following example returns a str ```razor @page "/call-js-example-5" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @implements IDisposable @inject IJSRuntime JS @@ -622,7 +622,7 @@ Add the preceding JS module to an app or class library as a static web asset in ```razor @page "/call-js-example-6" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @implements IAsyncDisposable @inject IJSRuntime JS @@ -846,7 +846,7 @@ The `{JAVASCRIPT FUNCTION}` placeholder is the JS function identifier. :::moniker range=">= aspnetcore-8.0" ```razor -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject IJSRuntime JS @using JsInteropClasses @@ -961,7 +961,7 @@ For a parent component to make an element reference available to other component ```razor @page "/call-js-example-7" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer

    Call JS Example 7

    @@ -1219,7 +1219,7 @@ Add the following `` element to the `` element markup ([location of ```razor @page "/call-js-example-8" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @implements IAsyncDisposable @inject IJSRuntime JS @@ -1331,7 +1331,7 @@ Provide a `receiveByteArray` JS function. The function is called with Call JS Example 9 @@ -1469,7 +1469,7 @@ In the following example, the `nonFunction` JS function doesn't exist. When the ```razor @page "/call-js-example-11" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject IJSRuntime JS

    Call JS Example 11

    @@ -1583,7 +1583,7 @@ The following `CallJsExample12` component: ```razor @page "/call-js-example-12" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @inject IJSRuntime JS

    Cancel long-running JS interop

    diff --git a/aspnetcore/blazor/javascript-interoperability/import-export-interop.md b/aspnetcore/blazor/javascript-interoperability/import-export-interop.md index 79c56568ffd3..4aff161e854a 100644 --- a/aspnetcore/blazor/javascript-interoperability/import-export-interop.md +++ b/aspnetcore/blazor/javascript-interoperability/import-export-interop.md @@ -65,7 +65,7 @@ In the following `CallJavaScript1` component: ```razor @page "/call-javascript-1" -@rendermode RenderMode.InteractiveWebAssembly +@rendermode InteractiveWebAssembly @using System.Runtime.InteropServices.JavaScript

    @@ -226,7 +226,7 @@ The following `CallDotNet1` component calls JS that directly interacts with the ```razor @page "/call-dotnet-1" -@rendermode RenderMode.InteractiveWebAssembly +@rendermode InteractiveWebAssembly @using System.Runtime.InteropServices.JavaScript

    @@ -479,7 +479,7 @@ if (OperatingSystem.IsBrowser()) ```razor @page "/call-javascript-2" -@rendermode RenderMode.InteractiveWebAssembly +@rendermode InteractiveWebAssembly @using BlazorSample.JavaScriptInterop

    @@ -532,7 +532,7 @@ if (OperatingSystem.IsBrowser()) ```razor @page "/call-dotnet-2" -@rendermode RenderMode.InteractiveWebAssembly +@rendermode InteractiveWebAssembly @using BlazorSample.JavaScriptInterop

    diff --git a/aspnetcore/blazor/javascript-interoperability/index.md b/aspnetcore/blazor/javascript-interoperability/index.md index 0c5c14ba3313..a9ec3599a111 100644 --- a/aspnetcore/blazor/javascript-interoperability/index.md +++ b/aspnetcore/blazor/javascript-interoperability/index.md @@ -122,7 +122,7 @@ In the following example, the `DOMCleanup` component: ```razor @page "/dom-cleanup" -@rendermode RenderMode.InteractiveServer +@rendermode InteractiveServer @implements IAsyncDisposable @inject IJSRuntime JS diff --git a/aspnetcore/blazor/javascript-interoperability/static-server-rendering.md b/aspnetcore/blazor/javascript-interoperability/static-server-rendering.md index f49382bcf9c5..e2299498ece0 100644 --- a/aspnetcore/blazor/javascript-interoperability/static-server-rendering.md +++ b/aspnetcore/blazor/javascript-interoperability/static-server-rendering.md @@ -18,13 +18,13 @@ uid: blazor/js-interop/ssr This article explains how to load JavaScript (JS) in a Blazor Web App with Static Server rendering and [enhanced navigation](xref:blazor/fundamentals/routing#enhanced-navigation-and-form-handling). -Some applications may depend on JS to perform initialization tasks that are specific to each page. When using Blazor's enhanced navigation feature, which allows the user to avoid reloading the entire page, JS code may not re-execute as expected. Therefore, page-specific `