is called:
->
-> ```csharp
-> app.UseAntiforgery();
-> ```
+The imported layout contains two `Home` (`Index` page) and `Privacy` navigation links. To make the `Home` links point to the hosted Blazor WebAssembly app, change the hyperlinks:
-Integrate components into any page or view. For example, add an `EmbeddedCounter` component to the project's `Components` folder.
+```diff
+- {PROJECT NAME}
++ BlazorHosted
+```
-`Components/EmbeddedCounter.razor`:
+```diff
+- Home
++ Home
+```
-```razor
-Embedded Counter
+In an MVC layout file:
-Current count: @currentCount
+```diff
+- {PROJECT NAME}
++ BlazorHosted
+```
-Click me
+```diff
+- Home
++ Home
+```
-@code {
- private int currentCount = 0;
+Update the `` element's app name. The following example uses the app name `BlazorHosted`:
- private void IncrementCount()
- {
- currentCount++;
- }
-}
+```diff
+- © {DATE} - {DONOR NAME} - Privacy
++ © {DATE} - BlazorHosted - Privacy
```
-**Razor Pages**:
+In the preceding example, the `{DATE}` placeholder represents the copyright date in an app generated from the Razor Pages or MVC project template.
-In the project's `Index` page of a Razor Pages app, add the `EmbeddedCounter` component's namespace and embed the component into the page. When the `Index` page loads, the `EmbeddedCounter` component is prerendered in the page. In the following example, replace the `{APP NAMESPACE}` placeholder with the project's namespace.
+To make the `Privacy` link lead to a privacy page (Razor Pages), add a privacy page to the **:::no-loc text="Server":::** project.
-`Pages/Index.cshtml`:
+`Pages/Privacy.cshtml` in the **:::no-loc text="Server":::** project:
```cshtml
@page
-@using {APP NAMESPACE}.Components
-@model IndexModel
+@model PrivacyModel
@{
- ViewData["Title"] = "Home page";
+ ViewData["Title"] = "Privacy Policy";
}
+@ViewData["Title"]
-
+Use this page to detail your site's privacy policy.
```
-**MVC**:
+For an MVC-based privacy view, create a privacy view in the **:::no-loc text="Server":::** project.
-In the project's `Index` view of an MVC app, add the `EmbeddedCounter` component's namespace and embed the component into the view. When the `Index` view loads, the `EmbeddedCounter` component is prerendered in the page. In the following example, replace the `{APP NAMESPACE}` placeholder with the project's namespace.
-
-`Views/Home/Index.cshtml`:
+`View/Home/Privacy.cshtml` in the **:::no-loc text="Server":::** project:
```cshtml
-@using {APP NAMESPACE}.Components
@{
- ViewData["Title"] = "Home Page";
+ ViewData["Title"] = "Privacy Policy";
}
+@ViewData["Title"]
+
+Use this page to detail your site's privacy policy.
+```
-
+In the `Home` controller of the MVC app, return the view.
+
+Add the following code to `Controllers/HomeController.cs`:
+
+```csharp
+public IActionResult Privacy()
+{
+ return View();
+}
```
-## Add Blazor support to an ASP.NET Core app
+If you import files from a donor app, be sure to update any namespaces in the files to match that of the **:::no-loc text="Server":::** project (for example, `BlazorHosted.Server`).
-This section covers adding Blazor support to an ASP.NET Core app:
+Import static assets to the **:::no-loc text="Server":::** project from the donor project's `wwwroot` folder:
-* [Add static server-side rendering (static SSR)](#add-static-server-side-rendering-static-ssr)
-* [Enable interactive server-side rendering (interactive SSR)](#enable-interactive-server-side-rendering-interactive-ssr)
-* [Enable interactive automatic (Auto) or client-side rendering (CSR)](#enable-interactive-automatic-auto-or-client-side-rendering-csr)
+* `wwwroot/css` folder and contents
+* `wwwroot/js` folder and contents
+* `wwwroot/lib` folder and contents
-> [!NOTE]
-> For the examples in this section, the example app's name and namespace is `BlazorSample`.
+If the donor project is created from an ASP.NET Core project template and the files aren't modified, you can copy the entire `wwwroot` folder from the donor project into the **:::no-loc text="Server":::** project and remove the :::no-loc text="favicon"::: icon file.
-### Add static server-side rendering (static SSR)
+> [!WARNING]
+> Avoid placing the static asset into both the **:::no-loc text="Client":::** and **:::no-loc text="Server":::** `wwwroot` folders. If the same file is present in both folders, an exception is thrown because the static assets share the same web root path. Therefore, host a static asset in either of the `wwwroot` folders, not both.
-Add a `Components` folder to the app.
+After adopting the preceding configuration, embed Razor components into pages or views of the **:::no-loc text="Server":::** project. Use the guidance in the following sections of this article:
-Add the following `_Imports` file for namespaces used by Razor components.
+* *Render components in a page or view with the Component Tag Helper*
+* *Render components in a page or view with a CSS selector*
-`Components/_Imports.razor`:
+## Render components in a page or view with the Component Tag Helper
-```razor
-@using System.Net.Http
-@using System.Net.Http.Json
-@using Microsoft.AspNetCore.Components.Forms
-@using Microsoft.AspNetCore.Components.Routing
-@using Microsoft.AspNetCore.Components.Web
-@using static Microsoft.AspNetCore.Components.Web.RenderMode
-@using Microsoft.AspNetCore.Components.Web.Virtualization
-@using Microsoft.JSInterop
-@using {APP NAMESPACE}
-@using {APP NAMESPACE}.Components
+After [configuring the solution](#solution-configuration), including the [additional configuration](#configuration-for-embedding-razor-components-into-pages-and-views), the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) supports two render modes for rendering a component from a Blazor WebAssembly app in a page or view:
+
+*
+*
+
+In the following Razor Pages example, the `Counter` component is rendered in a page. To make the component interactive, the Blazor WebAssembly script is included in the page's [render section](xref:mvc/views/layout#sections). To avoid using the full namespace for the `Counter` component with the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) (`{ASSEMBLY NAME}.Pages.Counter`), add an [`@using`](xref:mvc/views/razor#using) directive for the client project's `Pages` namespace. In the following example, the **:::no-loc text="Client":::** project's namespace is `BlazorHosted.Client`.
+
+In the **:::no-loc text="Server":::** project, `Pages/RazorPagesCounter1.cshtml`:
+
+```cshtml
+@page
+@using BlazorHosted.Client.Pages
+
+
+
+@section Scripts {
+
+}
```
-Change the namespace placeholder (`{APP NAMESPACE}`) to the namespace of the app. For example:
+Run the **:::no-loc text="Server":::** project. Navigate to the Razor page at `/razorpagescounter1`. The prerendered `Counter` component is embedded in the page.
+
+ configures whether the component:
+
+* Is prerendered into the page.
+* Is rendered as static HTML on the page or if it includes the necessary information to bootstrap a Blazor app from the user agent.
+
+For more information on the Component Tag Helper, including passing parameters and configuration, see .
+
+Additional work might be required depending on the static resources that components use and how layout pages are organized in an app. Typically, scripts are added to a page or view's `Scripts` render section and stylesheets are added to the layout's `` element content.
+
+### Set child content through a render fragment
+
+The [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) doesn't support receiving a [`RenderFragment` delegate for child content](xref:blazor/components/index#child-content-render-fragments) (for example, `param-ChildContent="..."`). We recommend creating a Razor component (`.razor`) that references the component you want to render with the child content you want to pass and then invoke the Razor component from the page or view.
+
+### Ensure that top-level prerendered components aren't trimmed out on publish
+
+If a [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) directly references a component from a library that's subject to trimming on publish, the component might be trimmed out during publish because there are no references to it from client-side app code. As a result, the component isn't prerendered, leaving a blank spot in the output. If this occurs, instruct the trimmer to preserve the library component by adding a [`DynamicDependency` attribute](xref:System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute) to any class in the client-side app. To preserve a component called `SomeLibraryComponentToBePreserved`, add the following to any component:
```razor
-@using BlazorSample
-@using BlazorSample.Components
+@using System.Diagnostics.CodeAnalysis
+@attribute [DynamicDependency(DynamicallyAccessedMemberTypes.All,
+ typeof(SomeLibraryComponentToBePreserved))]
```
-Add the Blazor router (``, ) to the app in a `Routes` component, which is placed in the app's `Components` folder.
+The preceding approach usually isn't required because the app usually prerenders its components (which are not trimmed), which in turn references components from libraries (causing them also not to be trimmed). Only use `DynamicDependency` explicitly for prerendering a library component directly when the library is subject to trimming.
-`Components/Routes.razor`:
+## Render components in a page or view with a CSS selector
-```razor
-
-
-
-
-
-
+After [configuring the solution](#solution-configuration), including the [additional configuration](#configuration-for-embedding-razor-components-into-pages-and-views), add root components to the **:::no-loc text="Client":::** project of a hosted Blazor WebAssembly solution in the `Program.cs` file. In the following example, the `Counter` component is declared as a root component with a CSS selector that selects the element with the `id` that matches `counter-component`. In the following example, the **:::no-loc text="Client":::** project's namespace is `BlazorHosted.Client`.
+
+In `Program.cs` file of the **:::no-loc text="Client":::** project, add the namespace for the project's Razor components to the top of the file:
+
+```csharp
+using BlazorHosted.Client.Pages;
```
-Add an `App` component to the app, which serves as the root component, which is the first component the app loads.
+After the `builder` is established in `Program.cs`, add the `Counter` component as a root component:
-`Components/App.razor`:
+```csharp
+builder.RootComponents.Add("#counter-component");
+```
-:::moniker range=">= aspnetcore-9.0"
+In the following Razor Pages example, the `Counter` component is rendered in a page. To make the component interactive, the Blazor WebAssembly script is included in the page's [render section](xref:mvc/views/layout#sections).
-```razor
-
-
+In the **:::no-loc text="Server":::** project, `Pages/RazorPagesCounter2.cshtml`:
-
-
-
-
-
-
-
+```cshtml
+@page
-
-
-
-
+Loading...
-
+@section Scripts {
+
+}
```
-:::moniker-end
+Run the **:::no-loc text="Server":::** project. Navigate to the Razor page at `/razorpagescounter2`. The prerendered `Counter` component is embedded in the page.
-:::moniker range="< aspnetcore-9.0"
+Additional work might be required depending on the static resources that components use and how layout pages are organized in an app. Typically, scripts are added to a page or view's `Scripts` render section and stylesheets are added to the layout's `` element content.
-```razor
-
-
+> [!NOTE]
+> The preceding example throws a if a Blazor WebAssembly app is prerendered and integrated into a Razor Pages or MVC app **simultaneously** with the use of a CSS selector. Navigating to one of the **:::no-loc text="Client":::** project's Razor components or navigating to a page or view of the **:::no-loc text="Server":::** with an embedded component throws one or more .
+>
+> This is normal behavior because prerendering and integrating a Blazor WebAssembly app with routable Razor components is incompatible with the use of CSS selectors.
+>
+> If you've been working with the examples in the preceding sections and just wish to see the CSS selector work in your sample app, comment out the specification of the `App` root component of the **:::no-loc text="Client":::** project's `Program.cs` file:
+>
+> ```diff
+> - builder.RootComponents.Add("#app");
+> + //builder.RootComponents.Add("#app");
+> ```
+>
+> Navigate to the page or view with the embedded Razor component that uses a CSS selector (for example, `/razorpagescounter2` of the preceding example). The page or view loads with the embedded component, and the embedded component functions as expected.
-
-
-
-
-
-
-
+:::zone-end
-
-
-
-
+:::zone pivot="server"
-
-```
+Razor components can be integrated into Razor Pages and MVC apps. When the page or view is rendered, components can be prerendered at the same time.
+
+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.
-:::moniker-end
+After [configuring the project](#configuration), use the guidance in the following sections depending on the project's requirements:
-The `{ASSEMBLY NAME}` placeholder is the app's assembly name. For example, a project with an assembly name of `ContosoApp` uses the `ContosoApp.styles.css` stylesheet file name.
+* For components that are directly routable from user requests. Follow this guidance when visitors should be able to make an HTTP request in their browser for a component with an [`@page`](xref:mvc/views/razor#page) directive.
+ * [Use routable components in a Razor Pages app](#use-routable-components-in-a-razor-pages-app)
+ * [Use routable components in an MVC app](#use-routable-components-in-an-mvc-app)
+* For components that aren't directly routable from user requests, see the [Render components from a page or view](#render-components-from-a-page-or-view) section. Follow this guidance when the app embeds components into existing pages and views with the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper).
-Add a `Pages` folder to the `Components` folder to hold routable Razor components.
+## Configuration
-Add the following `Welcome` component to demonstrate static SSR.
+Use the following guidance to integrate Razor components into pages and views of an existing Razor Pages or MVC app.
-`Components/Pages/Welcome.razor`:
+1. Add an imports file to the root folder of the project with the following content. Change the `{APP NAMESPACE}` placeholder to the namespace of the project.
-```razor
-@page "/welcome"
+ `_Imports.razor`:
-Welcome!
+ ```razor
+ @using System.Net.Http
+ @using Microsoft.AspNetCore.Authorization
+ @using Microsoft.AspNetCore.Components.Authorization
+ @using Microsoft.AspNetCore.Components.Forms
+ @using Microsoft.AspNetCore.Components.Routing
+ @using Microsoft.AspNetCore.Components.Web
+ @using Microsoft.AspNetCore.Components.Web.Virtualization
+ @using Microsoft.JSInterop
+ @using {APP NAMESPACE}
+ ```
-Welcome to Blazor!
+1. In the project's layout file (`Pages/Shared/_Layout.cshtml` in Razor Pages apps or `Views/Shared/_Layout.cshtml` in MVC apps):
-@message
+ * Add the following ` ` tag and component Tag Helper to the `` element:
-@code {
- private string message =
- "Hello from a Razor component and welcome to Blazor!";
-}
-```
+ ```cshtml
+
+
+ ```
-In the ASP.NET Core project's `Program` file:
+ The `href` value (the *app base path*) in the preceding example assumes that the app resides at the root URL path (`/`). If the app is a sub-application, follow the guidance in the *App base path* section of the article.
-* Add a `using` statement to the top of the file for the project's components:
+ The component is used to render head (``) content for page titles ( component) and other head elements ( component) set by Razor components. For more information, see .
- ```csharp
- using {APP NAMESPACE}.Components;
- ```
+ * Add a `
+ ```
- ```csharp
- using BlazorSample.Components;
- ```
+ The framework adds the `blazor.server.js` script to the app. There's no need to manually add a `blazor.server.js` script file to the app.
-* Add Razor component services (), which also automatically adds antiforgery services (). Add the following line before the line that calls `builder.Build()`):
+ > [!NOTE]
+ > Typically, the layout loads via a `_ViewStart.cshtml` file.
- ```csharp
- builder.Services.AddRazorComponents();
- ```
+1. Register the Blazor Server services in `Program.cs` where services are registered:
-* Add [Antiforgery Middleware](xref:blazor/security/index#antiforgery-support) to the request processing pipeline with . is called after the call to . If there are calls to and , the call to must go between them. A call to must be placed after calls to and .
+ ```csharp
+ builder.Services.AddServerSideBlazor();
+ ```
- ```csharp
- app.UseAntiforgery();
- ```
+1. Add the Blazor Hub endpoint to the endpoints of `Program.cs` where routes are mapped. Place the following line after the call to `MapRazorPages` (Razor Pages) or `MapControllerRoute` (MVC):
-* Add 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 line that calls `app.Run`:
+ ```csharp
+ app.MapBlazorHub();
+ ```
- ```csharp
- app.MapRazorComponents();
- ```
+1. Integrate components into any page or view. For example, add a `Counter` component to the project's `Shared` folder.
-When the app is run, the `Welcome` component is accessed at the `/welcome` endpoint.
+ `Pages/Shared/Counter.razor` (Razor Pages) or `Views/Shared/Counter.razor` (MVC):
-### Enable interactive server-side rendering (interactive SSR)
+ ```razor
+ Counter
-Follow the guidance in the [Add static server-side rendering (static SSR)](#add-static-server-side-rendering-static-ssr) section.
+ Current count: @currentCount
-In the app's `Program` file, add a call to where Razor component services are added with :
+ Click me
-```csharp
-builder.Services.AddRazorComponents()
- .AddInteractiveServerComponents();
-```
+ @code {
+ private int currentCount = 0;
-Add a call to where Razor components are mapped with :
+ private void IncrementCount()
+ {
+ currentCount++;
+ }
+ }
+ ```
-```csharp
-app.MapRazorComponents()
- .AddInteractiveServerRenderMode();
-```
+ **Razor Pages**:
-Add the following `Counter` component to the app that adopts interactive server-side rendering (interactive SSR).
+ In the project's `Index` page of a Razor Pages app, add the `Counter` component's namespace and embed the component into the page. When the `Index` page loads, the `Counter` component is prerendered in the page. In the following example, replace the `{APP NAMESPACE}` placeholder with the project's namespace.
-`Components/Pages/Counter.razor`:
+ `Pages/Index.cshtml`:
-```razor
-@page "/counter"
-@rendermode InteractiveServer
+ ```cshtml
+ @page
+ @using {APP NAMESPACE}.Pages.Shared
+ @model IndexModel
+ @{
+ ViewData["Title"] = "Home page";
+ }
-Counter
+
+ ```
-Counter
+ **MVC**:
-Current count: @currentCount
+ In the project's `Index` view of an MVC app, add the `Counter` component's namespace and embed the component into the view. When the `Index` view loads, the `Counter` component is prerendered in the page. In the following example, replace the `{APP NAMESPACE}` placeholder with the project's namespace.
-Click me
+ `Views/Home/Index.cshtml`:
-@code {
- private int currentCount = 0;
+ ```cshtml
+ @using {APP NAMESPACE}.Views.Shared
+ @{
+ ViewData["Title"] = "Home Page";
+ }
- private void IncrementCount()
- {
- currentCount++;
- }
-}
-```
+
+ ```
-When the app is run, the `Counter` component is accessed at `/counter`.
+For more information, see the [Render components from a page or view](#render-components-from-a-page-or-view) section.
-### Enable interactive automatic (Auto) or client-side rendering (CSR)
+## Use routable components in a Razor Pages app
-Follow the guidance in the [Add static server-side rendering (static SSR)](#add-static-server-side-rendering-static-ssr) section.
+*This section pertains to adding components that are directly routable from user requests.*
-Components using the Interactive Auto render mode initially use interactive SSR. The .NET runtime and app bundle are downloaded to the client in the background and cached so that they can be used on future visits. Components using the Interactive WebAssembly render mode only render interactively on the client after the Blazor bundle is downloaded and the Blazor runtime activates. Keep in mind that when using the Interactive Auto or Interactive WebAssembly render modes, component code downloaded to the client isn't private. For more information, see .
+To support routable Razor components in Razor Pages apps:
-After deciding which render mode to adopt:
+1. Follow the guidance in the [Configuration](#configuration) section.
-* If you plan to adopt the Interactive Auto render mode, follow the guidance in the [Enable interactive server-side rendering (interactive SSR)](#enable-interactive-server-side-rendering-interactive-ssr) section.
-* If you plan to only adopt Interactive WebAssembly rendering, continue without adding interactive SSR.
+1. Add an `App` component to the project root with the following content.
-Add a package reference for the [`Microsoft.AspNetCore.Components.WebAssembly.Server`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.WebAssembly.Server) NuGet package to the app.
+ `App.razor`:
-[!INCLUDE[](~/includes/package-reference.md)]
+ ```razor
+ @using Microsoft.AspNetCore.Components.Routing
-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.
+
+
+
+
+
+ Not found
+ Sorry, there's nothing at this address.
+
+
+ ```
-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.
+1. Add a `_Host` page to the project with the following content. Replace the `{APP NAMESPACE}` placeholder with the app's namespace.
-Visual Studio:
+ `Pages/_Host.cshtml`:
-* For **Interactive render mode**, select **Auto (Server and WebAssembly)**.
-* Set the **Interactivity location** to **Per page/component**.
-* Deselect the checkbox for **Include sample pages**.
+ ```cshtml
+ @page
+ @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
-.NET CLI:
+
+ ```
-* Use the `-int Auto` option.
-* Don't use the `-ai|--all-interactive` option.
-* Pass the `-e|--empty` option.
+ > [!NOTE]
+ > The preceding example assumes that the component and Blazor script (`_framework/blazor.server.js`) are rendered by the app's layout. For more information, see the [Configuration](#configuration) section.
+
+ configures whether the `App` component:
-From the donor Blazor Web App, copy the entire `.Client` project into the solution folder of the ASP.NET Core app.
+ * Is prerendered into the page.
+ * Is rendered as static HTML on the page or if it includes the necessary information to bootstrap a Blazor app from the user agent.
-> [!IMPORTANT]
-> **Don't copy the `.Client` folder into the ASP.NET Core project's folder.** The best approach for organizing .NET solutions is to place each project of the solution into its own folder inside of a top-level solution folder. If a solution folder above the ASP.NET Core project's folder doesn't exist, create one. Next, copy the `.Client` project's folder from the donor Blazor Web App into the solution folder. The final project folder structure should have the following layout:
->
-> * `BlazorSampleSolution` (top-level solution folder)
-> * `BlazorSample` (original ASP.NET Core project)
-> * `BlazorSample.Client` (`.Client` project folder from the donor Blazor Web App)
->
-> For the ASP.NET Core solution file, you can leave it in the ASP.NET Core project's folder. Alternatively, you can move the solution file or create a new one in the top-level solution folder as long as the project references correctly point to the project files (`.csproj`) of the two projects in the solution folder.
+ For more information on the Component Tag Helper, including passing parameters and configuration, see .
-If you named the donor Blazor Web App when you created the donor project the same as the ASP.NET Core app, the namespaces used by the donated assets match those in the ASP.NET Core app. You shouldn't need to take further steps to match namespaces. If you used a different namespace when creating the donor Blazor Web App project, you must adjust the namespaces across the donated assets to match if you intend to use the rest of this guidance exactly as presented. If the namespaces don't match, ***either*** adjust the namespaces before proceeding ***or*** adjust the namespaces as you follow the remaining guidance in this section.
+1. In the `Program.cs` endpoints, add a low-priority route for the `_Host` page as the last endpoint:
-Delete the donor Blazor Web App, as it has no further use in this process.
+ ```csharp
+ app.MapFallbackToPage("/_Host");
+ ```
-Add the `.Client` project to the solution:
+1. Add routable components to the project. The following example is a `RoutableCounter` component based on the `Counter` component in the Blazor project templates.
-* Visual Studio: Right-click the solution in **Solution Explorer** and select **Add** > **Existing Project**. Navigate to the `.Client` folder and select the project file (`.csproj`).
+ `Pages/RoutableCounter.razor`:
-* .NET CLI: Use the [`dotnet sln add` command](/dotnet/core/tools/dotnet-sln#add) to add the `.Client` project to the solution.
+ ```razor
+ @page "/routable-counter"
-Add a project reference from the ASP.NET Core project to the client project:
+ Routable Counter
-* Visual Studio: Right-click the ASP.NET Core project and select **Add** > **Project Reference**. Select the `.Client` project and select **OK**.
+ Routable Counter
-* .NET CLI: From the ASP.NET Core project's folder, use the following command:
+ Current count: @currentCount
- ```dotnetcli
- dotnet add reference ../BlazorSample.Client/BlazorSample.Client.csproj
- ```
+ Click me
- The preceding command assumes the following:
-
- * The project file name is `BlazorSample.Client.csproj`.
- * The `.Client` project is in a `BlazorSample.Client` folder inside the solution folder. The `.Client` folder is side-by-side with the ASP.NET Core project's folder.
-
- For more information on the `dotnet add reference` command, see [`dotnet add reference` (.NET documentation)](/dotnet/core/tools/dotnet-add-reference).
+ @code {
+ private int currentCount = 0;
-Make the following changes to the ASP.NET Core app's `Program` file:
+ private void IncrementCount()
+ {
+ currentCount++;
+ }
+ }
+ ```
-* Add Interactive WebAssembly component services with where Razor component services are added with .
+1. Run the project and navigate to the routable `RoutableCounter` component at `/routable-counter`.
- For interactive Auto rendering:
+For more information on namespaces, see the [Component namespaces](#component-namespaces) section.
- ```csharp
- builder.Services.AddRazorComponents()
- .AddInteractiveServerComponents()
- .AddInteractiveWebAssemblyComponents();
- ```
+## Use routable components in an MVC app
- For only Interactive WebAssembly rendering:
+*This section pertains to adding components that are directly routable from user requests.*
- ```csharp
- builder.Services.AddRazorComponents()
- .AddInteractiveWebAssemblyComponents();
- ```
+To support routable Razor components in MVC apps:
-* Add the Interactive WebAssembly render mode () and additional assemblies for the `.Client` project where Razor components are mapped with .
+1. Follow the guidance in the [Configuration](#configuration) section.
- For interactive automatic (Auto) rendering:
+1. Add an `App` component to the project root with the following content.
- ```csharp
- app.MapRazorComponents()
- .AddInteractiveServerRenderMode()
- .AddInteractiveWebAssemblyRenderMode()
- .AddAdditionalAssemblies(typeof(BlazorSample.Client._Imports).Assembly);
- ```
+ `App.razor`:
- For only Interactive WebAssembly rendering:
+ ```razor
+ @using Microsoft.AspNetCore.Components.Routing
- ```csharp
- app.MapRazorComponents()
- .AddInteractiveWebAssemblyRenderMode()
- .AddAdditionalAssemblies(typeof(BlazorSample.Client._Imports).Assembly);
- ```
+
+
+
+
+
+ Not found
+ Sorry, there's nothing at this address.
+
+
+ ```
- In the preceding examples, change `BlazorSample.Client` to match the `.Client` project's namespace.
+1. Add a `_Host` view to the project with the following content. Replace the `{APP NAMESPACE}` placeholder with the app's namespace.
-Add a `Pages` folder to the `.Client` project.
+ `Views/Home/_Host.cshtml`:
-If the ASP.NET Core project has an existing `Counter` component:
+ ```cshtml
+ @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
-* Move the component to the `Pages` folder of the `.Client` project.
-* Remove the `@rendermode` directive at the top of the component file.
+
+ ```
-If the ASP.NET Core app doesn't have a `Counter` component, add the following `Counter` component (`Pages/Counter.razor`) to the `.Client` project:
+ > [!NOTE]
+ > The preceding example assumes that the component and Blazor script (`_framework/blazor.server.js`) are rendered by the app's layout. For more information, see the [Configuration](#configuration) section.
-```razor
-@page "/counter"
-@rendermode InteractiveAuto
+ configures whether the `App` component:
-Counter
+ * Is prerendered into the page.
+ * Is rendered as static HTML on the page or if it includes the necessary information to bootstrap a Blazor app from the user agent.
-Counter
+ For more information on the Component Tag Helper, including passing parameters and configuration, see .
-Current count: @currentCount
+1. Add an action to the Home controller.
-Click me
+ `Controllers/HomeController.cs`:
-@code {
- private int currentCount = 0;
+ ```csharp
+ public IActionResult Blazor()
+ {
+ return View("_Host");
+ }
+ ```
- private void IncrementCount()
- {
- currentCount++;
- }
-}
-```
+1. In the `Program.cs` endpoints, add a low-priority route for the controller action that returns the `_Host` view:
-If the app is only adopting Interactive WebAssembly rendering, remove the `@rendermode` directive and value:
+ ```csharp
+ app.MapFallbackToController("Blazor", "Home");
+ ```
-```diff
-- @rendermode InteractiveAuto
-```
+1. Create a `Pages` folder in the MVC app and add routable components. The following example is a `RoutableCounter` component based on the `Counter` component in the Blazor project templates.
-Run the solution from the ***ASP.NET Core app*** project:
+ `Pages/RoutableCounter.razor`:
-* Visual Studio: Confirm that the ASP.NET Core project is selected in **Solution Explorer** when running the app.
+ ```razor
+ @page "/routable-counter"
-* .NET CLI: Run the project from the ASP.NET Core project's folder.
+ Routable Counter
-To load the `Counter` component, navigate to `/counter`.
+ Routable Counter
-### Implement Blazor's layout and styles
+ Current count: @currentCount
-Optionally, assign a default layout component using the parameter of the `RouteView` component.
+ Click me
-In `Routes.razor`, the following example uses a `MainLayout` component as the default layout:
+ @code {
+ private int currentCount = 0;
-```razor
-
-```
+ private void IncrementCount()
+ {
+ currentCount++;
+ }
+ }
+ ```
-For more information, see .
+1. Run the project and navigate to the routable `RoutableCounter` component at `/routable-counter`.
-Blazor project template layout and stylesheets are available from the [`dotnet/aspnetcore` GitHub repository](https://github.com/dotnet/aspnetcore/tree/main/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Layout):
+For more information on namespaces, see the [Component namespaces](#component-namespaces) section.
-* `MainLayout.razor`
-* `MainLayout.razor.css`
-* `NavMenu.razor`
-* `NavMenu.razor.css`
+## Render components from a page or view
-[!INCLUDE[](~/includes/aspnetcore-repo-ref-source-links.md)]
+*This section pertains to adding components to pages or views, where the components aren't directly routable from user requests.*
-Depending on how you organize your layout files in the app, you might need to add an `@using` statement for the layout files' folder in the app's `_Imports.razor` file in order to surface them for use in the app's components.
+To render a component from a page or view, use the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper).
-There's no need to explicitly reference stylesheets when using [CSS isolation](xref:blazor/components/css-isolation). The Blazor framework automatically bundles individual component stylesheets. The app's bundled stylesheet is already referenced in the app's `App` component (`{ASSEMBLY NAME}.styles.css`, where the `{ASSEMBLY NAME}` placeholder is the app's assembly name).
+### Render stateful interactive components
-## Return a `RazorComponentResult` from an MVC controller action
+Stateful interactive components can be added to a Razor page or view.
-An MVC controller action can return a component with .
+When the page or view renders:
-`Components/Welcome.razor`:
+* The component is prerendered with the page or view.
+* The initial component state used for prerendering is lost.
+* New component state is created when the SignalR connection is established.
-```razor
-Welcome!
+The following Razor page renders a `Counter` component:
-Welcome!
+```cshtml
+Razor Page
-@Message
+
-@code {
- [Parameter]
- public string? Message { get; set; }
+@functions {
+ [BindProperty(SupportsGet=true)]
+ public int InitialValue { get; set; }
}
```
-In a controller:
+For more information, see .
-```csharp
-public IResult GetWelcomeComponent() =>
- new RazorComponentResult(new { Message = "Hello, world!" });
-```
+### Render noninteractive components
-Only HTML markup for the rendered component is returned. Layouts and HTML page markup aren't automatically rendered with the component. To produce a complete HTML page, the app can maintain a [Blazor layout](xref:blazor/components/layouts) that provides HTML markup for ``, ``, ``, and other tags. The component includes the layout with the [`@layout`](xref:mvc/views/razor#layout) Razor directive at the top of the component definition file, `Welcome.razor` for the example in this section. The following example assumes that the app has a layout named `RazorComponentResultLayout` (`Components/Layout/RazorComponentResultLayout.razor`):
+In the following Razor page, the `Counter` component is statically rendered with an initial value that's specified using a form. Since the component is statically rendered, the component isn't interactive:
-```razor
-@using BlazorSample.Components.Layout
-@layout RazorComponentResultLayout
-```
+```cshtml
+Razor Page
+
+
-You can avoid placing the `@using` statement for the `Layout` folder in individual components by moving it to the app's `_Imports.razor` file.
+
-For more information, see .
+@functions {
+ [BindProperty(SupportsGet=true)]
+ public int InitialValue { get; set; }
+}
+```
+
+For more information, see .
## Component namespaces
@@ -614,16 +761,2300 @@ When using a custom folder to hold the project's Razor components, add the names
@using {APP NAMESPACE}.Components
```
-For example:
+The `_ViewImports.cshtml` file is located in the `Pages` folder of a Razor Pages app or the `Views` folder of an MVC app.
+
+For more information, see .
+
+:::zone-end
+
+## Persist prerendered state
+
+Without persisting prerendered state, state used during prerendering is lost and must be recreated when the app is fully loaded. If any state is setup asynchronously, the UI may flicker as the prerendered UI is replaced with temporary placeholders and then fully rendered again.
+
+To persist state for prerendered components, use the [Persist Component State Tag Helper](xref:mvc/views/tag-helpers/builtin-th/persist-component-state-tag-helper) ([reference source](https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.TagHelpers/src/PersistComponentStateTagHelper.cs)). Add the Tag Helper's tag, ` `, inside the closing `` tag of the `_Host` page in an app that prerenders components.
+
+[!INCLUDE[](~/includes/aspnetcore-repo-ref-source-links.md)]
+
+In `Pages/_Host.cshtml` of Blazor apps that are either WebAssembly prerendered (`WebAssemblyPrerendered`) in a hosted Blazor WebAssembly app or `ServerPrerendered` in a Blazor Server app:
```cshtml
-@using BlazorSample.Components
+
+ ...
+
+
+
```
-The `_ViewImports.cshtml` file is located in the `Pages` folder of a Razor Pages app or the `Views` folder of an MVC app.
+Decide what state to persist using the service. [`PersistentComponentState.RegisterOnPersisting`](xref:Microsoft.AspNetCore.Components.PersistentComponentState.RegisterOnPersisting%2A) registers a callback to persist the component state before the app is paused. The state is retrieved when the application resumes.
-For more information, see .
+In the following example:
+
+* The `{TYPE}` placeholder represents the type of data to persist (for example, `WeatherForecast[]`).
+* The `{TOKEN}` placeholder is a state identifier string (for example, `fetchdata`).
+
+```razor
+@implements IDisposable
+@inject PersistentComponentState ApplicationState
+
+...
+
+@code {
+ private {TYPE} data;
+ private PersistingComponentStateSubscription persistingSubscription;
+
+ protected override async Task OnInitializedAsync()
+ {
+ persistingSubscription =
+ ApplicationState.RegisterOnPersisting(PersistData);
+
+ if (!ApplicationState.TryTakeFromJson<{TYPE}>(
+ "{TOKEN}", out var restored))
+ {
+ data = await ...;
+ }
+ else
+ {
+ data = restored!;
+ }
+ }
+
+ private Task PersistData()
+ {
+ ApplicationState.PersistAsJson("{TOKEN}", data);
+
+ return Task.CompletedTask;
+ }
+
+ void IDisposable.Dispose()
+ {
+ persistingSubscription.Dispose();
+ }
+}
+```
+
+The following example is an updated version of the `FetchData` component in a hosted Blazor WebAssembly app based on the Blazor project template. The `WeatherForecastPreserveState` component persists weather forecast state during prerendering and then retrieves the state to initialize the component. The [Persist Component State Tag Helper](xref:mvc/views/tag-helpers/builtin-th/persist-component-state-tag-helper) persists the component state after all component invocations.
+
+`Pages/WeatherForecastPreserveState.razor`:
+
+```razor
+@page "/weather-forecast-preserve-state"
+@using BlazorSample.Shared
+@implements IDisposable
+@inject IWeatherForecastService WeatherForecastService
+@inject PersistentComponentState ApplicationState
+
+Weather Forecast
+
+Weather forecast
+
+This component demonstrates fetching data from the server.
+
+@if (forecasts == null)
+{
+ Loading...
+}
+else
+{
+
+
+
+ Date
+ Temp. (C)
+ Temp. (F)
+ Summary
+
+
+
+ @foreach (var forecast in forecasts)
+ {
+
+ @forecast.Date.ToShortDateString()
+ @forecast.TemperatureC
+ @forecast.TemperatureF
+ @forecast.Summary
+
+ }
+
+
+}
+
+@code {
+ private WeatherForecast[] forecasts = Array.Empty();
+ private PersistingComponentStateSubscription persistingSubscription;
+
+ protected override async Task OnInitializedAsync()
+ {
+ persistingSubscription =
+ ApplicationState.RegisterOnPersisting(PersistForecasts);
+
+ if (!ApplicationState.TryTakeFromJson(
+ "fetchdata", out var restored))
+ {
+ forecasts =
+ await WeatherForecastService.GetForecastAsync(DateOnly.FromDateTime(DateTime.Now));
+ }
+ else
+ {
+ forecasts = restored!;
+ }
+ }
+
+ private Task PersistForecasts()
+ {
+ ApplicationState.PersistAsJson("fetchdata", forecasts);
+
+ return Task.CompletedTask;
+ }
+
+ void IDisposable.Dispose()
+ {
+ persistingSubscription.Dispose();
+ }
+}
+```
+
+By initializing components with the same state used during prerendering, any expensive initialization steps are only executed once. The rendered UI also matches the prerendered UI, so no flicker occurs in the browser.
+
+The persisted prerendered state is transferred to the client, where it's used to restore the component state. [ASP.NET Core Data Protection](xref:security/data-protection/introduction) ensures that the data is transferred securely in Blazor Server apps. For prerendering in a hosted Blazor WebAssembly app, the data is exposed to the browser and must not contain sensitive, private information.
+
+:::zone pivot="webassembly"
+
+## Additional Blazor WebAssembly resources
+
+* [State management: Handle prerendering](xref:blazor/state-management#handle-prerendering)
+* [Prerendering support with assembly lazy loading](xref:blazor/webassembly-lazy-load-assemblies#lazy-load-assemblies-in-a-hosted-blazor-webassembly-solution)
+* Razor component lifecycle subjects that pertain to prerendering
+ * [Component initialization (`OnInitialized{Async}`)](xref:blazor/components/lifecycle#component-initialization-oninitializedasync)
+ * [After component render (`OnAfterRender{Async}`)](xref:blazor/components/lifecycle#after-component-render-onafterrenderasync)
+ * [Stateful reconnection after prerendering](xref:blazor/components/lifecycle#stateful-reconnection-after-prerendering): Although the content in the section focuses on Blazor Server and stateful SignalR *reconnection*, the scenario for prerendering in hosted Blazor WebAssembly apps () involves similar conditions and approaches to prevent executing developer code twice. To preserve state during the execution of initialization code while prerendering, see *Persist prerendered state* section of this article.
+ * [Prerendering with JavaScript interop](xref:blazor/components/lifecycle#prerendering-with-javascript-interop)
+* Authentication and authorization subjects that pertain to prerendering
+ * [General aspects](xref:blazor/security/index)
+ * [Prerendering with authentication in hosted Blazor WebAssembly apps](xref:blazor/security/webassembly/additional-scenarios#prerendering-with-authentication)
+* [Host and deploy: Blazor WebAssembly](xref:blazor/host-and-deploy/webassembly)
+* [Handle errors: Prerendering](xref:blazor/fundamentals/handle-errors#prerendering)
+* is executed *twice* when prerendering: [Handle asynchronous navigation events with `OnNavigateAsync`](xref:blazor/fundamentals/routing#handle-asynchronous-navigation-events-with-onnavigateasync)
+
+:::zone-end
+
+:::zone pivot="server"
+
+## Prerendered state size and SignalR message size limit
+
+A large prerendered state size may exceed the SignalR circuit message size limit, which results in the following:
+
+* The SignalR circuit fails to initialize with an error on the client: :::no-loc text="Circuit host not initialized.":::
+* The reconnection UI on the client appears when the circuit fails. Recovery isn't possible.
+
+To resolve the problem, use ***either*** of the following approaches:
+
+* Reduce the amount of data that you are putting into the prerendered state.
+* Increase the [SignalR message size limit](xref:blazor/fundamentals/signalr#server-side-circuit-handler-options). ***WARNING***: Increasing the limit may increase the risk of Denial of Service (DoS) attacks.
+
+## Additional Blazor Server resources
+
+* [State management: Handle prerendering](xref:blazor/state-management#handle-prerendering)
+* Razor component lifecycle subjects that pertain to prerendering
+ * [Component initialization (`OnInitialized{Async}`)](xref:blazor/components/lifecycle#component-initialization-oninitializedasync)
+ * [After component render (`OnAfterRender{Async}`)](xref:blazor/components/lifecycle#after-component-render-onafterrenderasync)
+ * [Stateful reconnection after prerendering](xref:blazor/components/lifecycle#stateful-reconnection-after-prerendering)
+ * [Prerendering with JavaScript interop](xref:blazor/components/lifecycle#prerendering-with-javascript-interop)
+* [Authentication and authorization: General aspects](xref:blazor/security/index#aspnet-core-blazor-authentication-and-authorization)
+* [Handle Errors: Prerendering](xref:blazor/fundamentals/handle-errors#prerendering)
+* [Host and deploy: Blazor Server](xref:blazor/host-and-deploy/server)
+* [Threat mitigation: Cross-site scripting (XSS)](xref:blazor/security/server/interactive-server-side-rendering#cross-site-scripting-xss)
+* is executed *twice* when prerendering: [Handle asynchronous navigation events with `OnNavigateAsync`](xref:blazor/fundamentals/routing#handle-asynchronous-navigation-events-with-onnavigateasync)
+
+:::zone-end
+
+:::moniker-end
+
+:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
+
+:::zone pivot="webassembly"
+
+Razor components can be integrated into Razor Pages and MVC apps in a hosted Blazor WebAssembly [solution](xref:blazor/tooling#visual-studio-solution-file-sln). When the page or view is rendered, components can be prerendered at the same time.
+
+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.
+
+## Solution configuration
+
+### Prerendering configuration
+
+To set up prerendering for a hosted Blazor WebAssembly app:
-## Additional resources
+1. Host the Blazor WebAssembly app in an ASP.NET Core app. A standalone Blazor WebAssembly app can be added to an ASP.NET Core solution, or you can use a hosted Blazor WebAssembly app created from the [Blazor WebAssembly project template](xref:blazor/tooling) with the hosted option:
-
+ * Visual Studio: In the **Additional information** dialog, select the **ASP.NET Core Hosted** checkbox when creating the Blazor WebAssembly app. In this article's examples, the solution is named `BlazorHosted`.
+ * Visual Studio Code/.NET CLI command shell: `dotnet new blazorwasm -ho` (use the `-ho|--hosted` option). Use the `-o|--output {LOCATION}` option to create a folder for the solution and set the solution's project namespaces. In this article's examples, the solution is named `BlazorHosted` (`dotnet new blazorwasm -ho -o BlazorHosted`).
+
+ For the examples in this article, the client project's namespace is `BlazorHosted.Client`, and the server project's namespace is `BlazorHosted.Server`.
+
+1. **Delete** the `wwwroot/index.html` file from the Blazor WebAssembly **:::no-loc text="Client":::** project.
+
+1. In the **:::no-loc text="Client":::** project, **delete** the following lines in `Program.cs`:
+
+ ```diff
+ - builder.RootComponents.Add("#app");
+ - builder.RootComponents.Add("head::after");
+ ```
+
+1. Add `_Host.cshtml` and `_Layout.cshtml` files to the **:::no-loc text="Server":::** project's `Pages` folder. You can obtain the files from a project created from the Blazor Server template using Visual Studio or using the .NET CLI with the `dotnet new blazorserver -o BlazorServer` command in a command shell (the `-o BlazorServer` option creates a folder for the project). After placing the files into the **:::no-loc text="Server":::** project's `Pages` folder, make the following changes to the files.
+
+ > [!IMPORTANT]
+ > The use of a layout page (`_Layout.cshtml`) with a [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) for a component is required to control `` content, such as the page's title ( component) and other head elements ( component). For more information, see .
+
+ Make the following changes to the `_Layout.cshtml` file:
+
+ * Update the `Pages` namespace at the top of the file to match the namespace of the **:::no-loc text="Server":::** app's pages. The `{APP NAMESPACE}` placeholder in the following example represents the namespace of the donor app's pages that provided the `_Layout.cshtml` file:
+
+ Delete:
+
+ ```diff
+ - @namespace {APP NAMESPACE}.Pages
+ ```
+
+ Add:
+
+ ```razor
+ @namespace BlazorHosted.Server.Pages
+ ```
+
+ * Add an [`@using`](xref:mvc/views/razor#using) directive for the **:::no-loc text="Client":::** project at the top of the file:
+
+ ```razor
+ @using BlazorHosted.Client
+ ```
+
+ * Update the stylesheet links to point to the WebAssembly project's stylesheets. In the following example, the client project's namespace is `BlazorHosted.Client`. The `{APP NAMESPACE}` placeholder represents the namespace of the donor app that provided the `_Layout.cshtml` file. Update the Component Tag Helper (`` tag) for the `HeadOutlet` component to prerender the component.
+
+ Delete:
+
+ ```diff
+ -
+ -
+ -
+ ```
+
+ Add:
+
+ ```cshtml
+
+
+
+ ```
+
+ > [!NOTE]
+ > Leave the ` ` element that requests the Bootstrap stylesheet (`css/bootstrap/bootstrap.min.css`) in place.
+
+ * Update the Blazor script source to use the client-side Blazor WebAssembly script:
+
+ Delete:
+
+ ```diff
+ -
+ ```
+
+ Add:
+
+ ```html
+
+ ```
+
+ In the `_Host.cshtml` file:
+
+ * Change the `Pages` namespace to that of the **:::no-loc text="Client":::** project. The `{APP NAMESPACE}` placeholder represents the namespace of the donor app's pages that provided the `_Host.cshtml` file:
+
+ Delete:
+
+ ```diff
+ - @namespace {APP NAMESPACE}.Pages
+ ```
+
+ Add:
+
+ ```razor
+ @namespace BlazorHosted.Client
+ ```
+
+ * Update the `render-mode` of the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) to prerender the root `App` component with :
+
+ Delete:
+
+ ```diff
+ -
+ ```
+
+ Add:
+
+ ```cshtml
+
+ ```
+
+ > [!IMPORTANT]
+ > Prerendering isn't supported for authentication endpoints (`/authentication/` path segment). For more information, see .
+
+1. In endpoint mapping of the **:::no-loc text="Server":::** project in `Program.cs`, change the fallback from the `index.html` file to the `_Host.cshtml` page:
+
+ Delete:
+
+ ```diff
+ - app.MapFallbackToFile("index.html");
+ ```
+
+ Add:
+
+ ```csharp
+ app.MapFallbackToPage("/_Host");
+ ```
+
+1. If the **:::no-loc text="Client":::** and **:::no-loc text="Server":::** projects use one or more common services during prerendering, factor the service registrations into a method that can be called from both projects. For more information, see .
+
+1. Run the **:::no-loc text="Server":::** project. The hosted Blazor WebAssembly app is prerendered by the **:::no-loc text="Server":::** project for clients.
+
+### Configuration for embedding Razor components into pages and views
+
+The following sections and examples for embedding Razor components from the **:::no-loc text="Client":::** Blazor WebAssembly app into pages and views of the server app require additional configuration.
+
+The **:::no-loc text="Server":::** project must have the following files and folders.
+
+Razor Pages:
+
+* `Pages/Shared/_Layout.cshtml`
+* `Pages/Shared/_Layout.cshtml.css`
+* `Pages/_ViewImports.cshtml`
+* `Pages/_ViewStart.cshtml`
+
+MVC:
+
+* `Views/Shared/_Layout.cshtml`
+* `Views/Shared/_Layout.cshtml.css`
+* `Views/_ViewImports.cshtml`
+* `Views/_ViewStart.cshtml`
+
+> [!IMPORTANT]
+> The use of a layout page (`_Layout.cshtml`) with a [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) for a component is required to control `` content, such as the page's title ( component) and other head elements ( component). For more information, see .
+
+The preceding files can be obtained by generating an app from the ASP.NET Core project templates using:
+
+* Visual Studio's new project creation tools.
+* Opening a command shell and executing `dotnet new webapp -o {PROJECT NAME}` (Razor Pages) or `dotnet new mvc -o {PROJECT NAME}` (MVC). The option `-o|--output` with a value for the `{PROJECT NAME}` placeholder provides a name for the app and creates a folder for the app.
+
+Update the namespaces in the imported `_ViewImports.cshtml` file to match those in use by the **:::no-loc text="Server":::** project receiving the files.
+
+`Pages/_ViewImports.cshtml` (Razor Pages):
+
+```razor
+@using BlazorHosted.Server
+@namespace BlazorHosted.Server.Pages
+@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
+```
+
+`Views/_ViewImports.cshtml` (MVC):
+
+```razor
+@using BlazorHosted.Server
+@using BlazorHosted.Server.Models
+@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
+```
+
+Update the imported layout file, which is `Pages/Shared/_Layout.cshtml` for Razor Pages or `Views/Shared/_Layout.cshtml` for MVC.
+
+First, delete the title and the stylesheet from the donor project, which is `RPDonor.styles.css` in the following example. The `{PROJECT NAME}` placeholder represents the donor project's app name.
+
+```diff
+- @ViewData["Title"] - {PROJECT NAME}
+-
+```
+
+Include the **:::no-loc text="Client":::** project's styles in the layout file. In the following example, the **:::no-loc text="Client":::** project's namespace is `BlazorHosted.Client`. The `` element can be updated at the same time.
+
+Place the following lines in the `` content of the layout file:
+
+```cshtml
+@ViewData["Title"] - BlazorHosted
+
+
+
+```
+
+The imported layout contains two `Home` (`Index` page) and `Privacy` navigation links. To make the `Home` links point to the hosted Blazor WebAssembly app, change the hyperlinks:
+
+```diff
+- {PROJECT NAME}
++ BlazorHosted
+```
+
+```diff
+- Home
++ Home
+```
+
+In an MVC layout file:
+
+```diff
+- {PROJECT NAME}
++ BlazorHosted
+```
+
+```diff
+- Home
++ Home
+```
+
+Update the `` element's app name. The following example uses the app name `BlazorHosted`:
+
+```diff
+- © {DATE} - {DONOR NAME} - Privacy
++ © {DATE} - BlazorHosted - Privacy
+```
+
+In the preceding example, the `{DATE}` placeholder represents the copyright date in an app generated from the Razor Pages or MVC project template.
+
+To make the `Privacy` link lead to a privacy page (Razor Pages), add a privacy page to the **:::no-loc text="Server":::** project.
+
+`Pages/Privacy.cshtml` in the **:::no-loc text="Server":::** project:
+
+```cshtml
+@page
+@model PrivacyModel
+@{
+ ViewData["Title"] = "Privacy Policy";
+}
+@ViewData["Title"]
+
+Use this page to detail your site's privacy policy.
+```
+
+For an MVC-based privacy view, create a privacy view in the **:::no-loc text="Server":::** project.
+
+`View/Home/Privacy.cshtml` in the **:::no-loc text="Server":::** project:
+
+```cshtml
+@{
+ ViewData["Title"] = "Privacy Policy";
+}
+@ViewData["Title"]
+
+Use this page to detail your site's privacy policy.
+```
+
+In the `Home` controller of the MVC app, return the view.
+
+Add the following code to `Controllers/HomeController.cs`:
+
+```csharp
+public IActionResult Privacy()
+{
+ return View();
+}
+```
+
+If you import files from a donor app, be sure to update any namespaces in the files to match that of the **:::no-loc text="Server":::** project (for example, `BlazorHosted.Server`).
+
+Import static assets to the **:::no-loc text="Server":::** project from the donor project's `wwwroot` folder:
+
+* `wwwroot/css` folder and contents
+* `wwwroot/js` folder and contents
+* `wwwroot/lib` folder and contents
+
+If the donor project is created from an ASP.NET Core project template and the files aren't modified, you can copy the entire `wwwroot` folder from the donor project into the **:::no-loc text="Server":::** project and remove the :::no-loc text="favicon"::: icon file.
+
+> [!WARNING]
+> Avoid placing the static asset into both the **:::no-loc text="Client":::** and **:::no-loc text="Server":::** `wwwroot` folders. If the same file is present in both folders, an exception is thrown because the static asset in each folder shares the same web root path. Therefore, host a static asset in either `wwwroot` folder, not both.
+
+After adopting the preceding configuration, embed Razor components into pages or views of the **:::no-loc text="Server":::** project. Use the guidance in the following sections of this article:
+
+* *Render components in a page or view with the Component Tag Helper*
+* *Render components in a page or view with a CSS selector*
+
+## Render components in a page or view with the Component Tag Helper
+
+After [configuring the solution](#solution-configuration), including the [additional configuration](#configuration-for-embedding-razor-components-into-pages-and-views), the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) supports two render modes for rendering a component from a Blazor WebAssembly app in a page or view:
+
+*
+*
+
+In the following Razor Pages example, the `Counter` component is rendered in a page. To make the component interactive, the Blazor WebAssembly script is included in the page's [render section](xref:mvc/views/layout#sections). To avoid using the full namespace for the `Counter` component with the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) (`{ASSEMBLY NAME}.Pages.Counter`), add an [`@using`](xref:mvc/views/razor#using) directive for the client project's `Pages` namespace. In the following example, the **:::no-loc text="Client":::** project's namespace is `BlazorHosted.Client`.
+
+In the **:::no-loc text="Server":::** project, `Pages/RazorPagesCounter1.cshtml`:
+
+```cshtml
+@page
+@using BlazorHosted.Client.Pages
+
+
+
+@section Scripts {
+
+}
+```
+
+Run the **:::no-loc text="Server":::** project. Navigate to the Razor page at `/razorpagescounter1`. The prerendered `Counter` component is embedded in the page.
+
+ configures whether the component:
+
+* Is prerendered into the page.
+* Is rendered as static HTML on the page or if it includes the necessary information to bootstrap a Blazor app from the user agent.
+
+For more information on the Component Tag Helper, including passing parameters and configuration, see .
+
+Additional work might be required depending on the static resources that components use and how layout pages are organized in an app. Typically, scripts are added to a page or view's `Scripts` render section and stylesheets are added to the layout's `` element content.
+
+### Set child content through a render fragment
+
+The [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) doesn't support receiving a [`RenderFragment` delegate for child content](xref:blazor/components/index#child-content-render-fragments) (for example, `param-ChildContent="..."`). We recommend creating a Razor component (`.razor`) that references the component you want to render with the child content you want to pass and then invoke the Razor component from the page or view.
+
+### Ensure that top-level prerendered components aren't trimmed out on publish
+
+If a [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) directly references a component from a library that's subject to trimming on publish, the component might be trimmed out during publish because there are no references to it from client-side app code. As a result, the component isn't prerendered, leaving a blank spot in the output. If this occurs, instruct the trimmer to preserve the library component by adding a [`DynamicDependency` attribute](xref:System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute) to any class in the client-side app. To preserve a component called `SomeLibraryComponentToBePreserved`, add the following to any component:
+
+```razor
+@using System.Diagnostics.CodeAnalysis
+@attribute [DynamicDependency(DynamicallyAccessedMemberTypes.All,
+ typeof(SomeLibraryComponentToBePreserved))]
+```
+
+The preceding approach usually isn't required because the app usually prerenders its components (which are not trimmed), which in turn references components from libraries (causing them also not to be trimmed). Only use `DynamicDependency` explicitly for prerendering a library component directly when the library is subject to trimming.
+
+## Render components in a page or view with a CSS selector
+
+After [configuring the solution](#solution-configuration), including the [additional configuration](#configuration-for-embedding-razor-components-into-pages-and-views), add root components to the **:::no-loc text="Client":::** project of a hosted Blazor WebAssembly solution in the `Program.cs` file. In the following example, the `Counter` component is declared as a root component with a CSS selector that selects the element with the `id` that matches `counter-component`. In the following example, the **:::no-loc text="Client":::** project's namespace is `BlazorHosted.Client`.
+
+In `Program.cs` file of the **:::no-loc text="Client":::** project, add the namespace for the project's Razor components to the top of the file:
+
+```csharp
+using BlazorHosted.Client.Pages;
+```
+
+After the `builder` is established in `Program.cs`, add the `Counter` component as a root component:
+
+```csharp
+builder.RootComponents.Add("#counter-component");
+```
+
+In the following Razor Pages example, the `Counter` component is rendered in a page. To make the component interactive, the Blazor WebAssembly script is included in the page's [render section](xref:mvc/views/layout#sections).
+
+In the **:::no-loc text="Server":::** project, `Pages/RazorPagesCounter2.cshtml`:
+
+```cshtml
+@page
+
+Loading...
+
+@section Scripts {
+
+}
+```
+
+Run the **:::no-loc text="Server":::** project. Navigate to the Razor page at `/razorpagescounter2`. The prerendered `Counter` component is embedded in the page.
+
+Additional work might be required depending on the static resources that components use and how layout pages are organized in an app. Typically, scripts are added to a page or view's `Scripts` render section and stylesheets are added to the layout's `` element content.
+
+> [!NOTE]
+> The preceding example throws a if a Blazor WebAssembly app is prerendered and integrated into a Razor Pages or MVC app **simultaneously** with the use of a CSS selector. Navigating to one of the **:::no-loc text="Client":::** project's Razor components or navigating to a page or view of the **:::no-loc text="Server":::** with an embedded component throws one or more .
+>
+> This is normal behavior because prerendering and integrating a Blazor WebAssembly app with routable Razor components is incompatible with the use of CSS selectors.
+>
+> If you've been working with the examples in the preceding sections and just wish to see the CSS selector work in your sample app, comment out the specification of the `App` root component of the **:::no-loc text="Client":::** project's `Program.cs` file:
+>
+> ```diff
+> - builder.RootComponents.Add("#app");
+> + //builder.RootComponents.Add("#app");
+> ```
+>
+> Navigate to the page or view with the embedded Razor component that uses a CSS selector (for example, `/razorpagescounter2` of the preceding example). The page or view loads with the embedded component, and the embedded component functions as expected.
+
+:::zone-end
+
+:::zone pivot="server"
+
+Razor components can be integrated into Razor Pages and MVC apps. When the page or view is rendered, components can be prerendered at the same time.
+
+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.
+
+After [configuring the project](#configuration), use the guidance in the following sections depending on the project's requirements:
+
+* Routable components: For components that are directly routable from user requests. Follow this guidance when visitors should be able to make an HTTP request in their browser for a component with an [`@page`](xref:mvc/views/razor#page) directive.
+ * [Use routable components in a Razor Pages app](#use-routable-components-in-a-razor-pages-app)
+ * [Use routable components in an MVC app](#use-routable-components-in-an-mvc-app)
+* [Render components from a page or view](#render-components-from-a-page-or-view): For components that aren't directly routable from user requests. Follow this guidance when the app embeds components into existing pages and views with the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper).
+
+## Configuration
+
+Use the following guidance to integrate Razor components into pages and views of an existing Razor Pages or MVC app.
+
+> [!IMPORTANT]
+> The use of a layout page (`_Layout.cshtml`) with a [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) for a component is required to control `` content, such as the page's title ( component) and other head elements ( component). For more information, see .
+
+1. In the project's layout file:
+
+ * Add the following ` ` tag and component Tag Helper to the `` element in `Pages/Shared/_Layout.cshtml` (Razor Pages) or `Views/Shared/_Layout.cshtml` (MVC):
+
+ ```cshtml
+
+
+ ```
+
+ The `href` value (the *app base path*) in the preceding example assumes that the app resides at the root URL path (`/`). If the app is a sub-application, follow the guidance in the *App base path* section of the article.
+
+ The component is used to render head (``) content for page titles ( component) and other head elements ( component) set by Razor components. For more information, see .
+
+ * Add a `
+ ```
+
+ The framework adds the `blazor.server.js` script to the app. There's no need to manually add a `blazor.server.js` script file to the app.
+
+1. Add an imports file to the root folder of the project with the following content. Change the `{APP NAMESPACE}` placeholder to the namespace of the project.
+
+ `_Imports.razor`:
+
+ ```razor
+ @using System.Net.Http
+ @using Microsoft.AspNetCore.Authorization
+ @using Microsoft.AspNetCore.Components.Authorization
+ @using Microsoft.AspNetCore.Components.Forms
+ @using Microsoft.AspNetCore.Components.Routing
+ @using Microsoft.AspNetCore.Components.Web
+ @using Microsoft.AspNetCore.Components.Web.Virtualization
+ @using Microsoft.JSInterop
+ @using {APP NAMESPACE}
+ ```
+
+1. Register the Blazor Server services in `Program.cs` where services are registered:
+
+ ```csharp
+ builder.Services.AddServerSideBlazor();
+ ```
+
+1. Add the Blazor Hub endpoint to the endpoints of `Program.cs` where routes are mapped.
+
+ Place the following line after the call to `MapRazorPages` (Razor Pages) or `MapControllerRoute` (MVC):
+
+ ```csharp
+ app.MapBlazorHub();
+ ```
+
+1. Integrate components into any page or view. For example, add a `Counter` component to the project's `Shared` folder.
+
+ `Pages/Shared/Counter.razor` (Razor Pages) or `Views/Shared/Counter.razor` (MVC):
+
+ ```razor
+ Counter
+
+ Current count: @currentCount
+
+ Click me
+
+ @code {
+ private int currentCount = 0;
+
+ private void IncrementCount()
+ {
+ currentCount++;
+ }
+ }
+ ```
+
+ **Razor Pages**:
+
+ In the project's `Index` page of a Razor Pages app, add the `Counter` component's namespace and embed the component into the page. When the `Index` page loads, the `Counter` component is prerendered in the page. In the following example, replace the `{APP NAMESPACE}` placeholder with the project's namespace.
+
+ `Pages/Index.cshtml`:
+
+ ```cshtml
+ @page
+ @using {APP NAMESPACE}.Pages.Shared
+ @model IndexModel
+ @{
+ ViewData["Title"] = "Home page";
+ }
+
+
+ ```
+
+ **MVC**:
+
+ In the project's `Index` view of an MVC app, add the `Counter` component's namespace and embed the component into the view. When the `Index` view loads, the `Counter` component is prerendered in the page. In the following example, replace the `{APP NAMESPACE}` placeholder with the project's namespace.
+
+ `Views/Home/Index.cshtml`:
+
+ ```cshtml
+ @using {APP NAMESPACE}.Views.Shared
+ @{
+ ViewData["Title"] = "Home Page";
+ }
+
+
+ ```
+
+For more information, see the [Render components from a page or view](#render-components-from-a-page-or-view) section.
+
+## Use routable components in a Razor Pages app
+
+*This section pertains to adding components that are directly routable from user requests.*
+
+To support routable Razor components in Razor Pages apps:
+
+1. Follow the guidance in the [Configuration](#configuration) section.
+
+1. Add an `App` component to the project root with the following content.
+
+ `App.razor`:
+
+ ```razor
+ @using Microsoft.AspNetCore.Components.Routing
+
+
+
+
+
+
+ Not found
+ Sorry, there's nothing at this address.
+
+
+ ```
+
+1. Add a `_Host` page to the project with the following content.
+
+ `Pages/_Host.cshtml`:
+
+ ```cshtml
+ @page "/blazor"
+ @namespace {APP NAMESPACE}.Pages.Shared
+ @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
+ @{
+ Layout = "_Layout";
+ }
+
+
+ ```
+
+ In this scenario, components use the shared `_Layout.cshtml` file for their layout.
+
+ > [!IMPORTANT]
+ > The use of a layout page (`_Layout.cshtml`) with a [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) for a component is required to control `` content, such as the page's title ( component) and other head elements ( component). For more information, see .
+
+ configures whether the `App` component:
+
+ * Is prerendered into the page.
+ * Is rendered as static HTML on the page or if it includes the necessary information to bootstrap a Blazor app from the user agent.
+
+ For more information on the Component Tag Helper, including passing parameters and configuration, see .
+
+1. In the `Program.cs` endpoints, add a low-priority route for the `_Host` page as the last endpoint:
+
+ ```csharp
+ app.MapFallbackToPage("/_Host");
+ ```
+
+1. Add routable components to the project. The following example is a `RoutableCounter` component based on the `Counter` component in the Blazor project templates.
+
+ `Pages/RoutableCounter.razor`:
+
+ ```razor
+ @page "/routable-counter"
+
+ Routable Counter
+
+ Routable Counter
+
+ Current count: @currentCount
+
+ Click me
+
+ @code {
+ private int currentCount = 0;
+
+ private void IncrementCount()
+ {
+ currentCount++;
+ }
+ }
+ ```
+
+1. Run the project and navigate to the routable `RoutableCounter` component at `/routable-counter`.
+
+For more information on namespaces, see the [Component namespaces](#component-namespaces) section.
+
+## Use routable components in an MVC app
+
+*This section pertains to adding components that are directly routable from user requests.*
+
+To support routable Razor components in MVC apps:
+
+1. Follow the guidance in the [Configuration](#configuration) section.
+
+1. Add an `App` component to the project root with the following content.
+
+ `App.razor`:
+
+ ```razor
+ @using Microsoft.AspNetCore.Components.Routing
+
+
+
+
+
+
+ Not found
+ Sorry, there's nothing at this address.
+
+
+ ```
+
+1. Add a `_Host` view to the project with the following content.
+
+ `Views/Home/_Host.cshtml`:
+
+ ```cshtml
+ @namespace {APP NAMESPACE}.Views.Shared
+ @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
+ @{
+ Layout = "_Layout";
+ }
+
+
+ ```
+
+ Components use the shared `_Layout.cshtml` file for their layout.
+
+ > [!IMPORTANT]
+ > The use of a layout page (`_Layout.cshtml`) with a [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) for a component is required to control `` content, such as the page's title ( component) and other head elements ( component). For more information, see .
+
+ configures whether the `App` component:
+
+ * Is prerendered into the page.
+ * Is rendered as static HTML on the page or if it includes the necessary information to bootstrap a Blazor app from the user agent.
+
+ For more information on the Component Tag Helper, including passing parameters and configuration, see .
+
+1. Add an action to the Home controller.
+
+ `Controllers/HomeController.cs`:
+
+ ```csharp
+ public IActionResult Blazor()
+ {
+ return View("_Host");
+ }
+ ```
+
+1. In the `Program.cs` endpoints, add a low-priority route for the controller action that returns the `_Host` view:
+
+ ```csharp
+ app.MapFallbackToController("Blazor", "Home");
+ ```
+
+1. Create a `Pages` folder in the MVC app and add routable components. The following example is a `RoutableCounter` component based on the `Counter` component in the Blazor project templates.
+
+ `Pages/RoutableCounter.razor`:
+
+ ```razor
+ @page "/routable-counter"
+
+ Routable Counter
+
+ Routable Counter
+
+ Current count: @currentCount
+
+ Click me
+
+ @code {
+ private int currentCount = 0;
+
+ private void IncrementCount()
+ {
+ currentCount++;
+ }
+ }
+ ```
+
+1. Run the project and navigate to the routable `RoutableCounter` component at `/routable-counter`.
+
+For more information on namespaces, see the [Component namespaces](#component-namespaces) section.
+
+## Render components from a page or view
+
+*This section pertains to adding components to pages or views, where the components aren't directly routable from user requests.*
+
+To render a component from a page or view, use the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper).
+
+### Render stateful interactive components
+
+Stateful interactive components can be added to a Razor page or view.
+
+When the page or view renders:
+
+* The component is prerendered with the page or view.
+* The initial component state used for prerendering is lost.
+* New component state is created when the SignalR connection is established.
+
+The following Razor page renders a `Counter` component:
+
+```cshtml
+Razor Page
+
+
+
+@functions {
+ [BindProperty(SupportsGet=true)]
+ public int InitialValue { get; set; }
+}
+```
+
+For more information, see .
+
+> [!IMPORTANT]
+> The use of a layout page (`_Layout.cshtml`) with a [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) for a component is required to control `` content, such as the page's title ( component) and other head elements ( component). For more information, see .
+
+### Render noninteractive components
+
+In the following Razor page, the `Counter` component is statically rendered with an initial value that's specified using a form. Since the component is statically rendered, the component isn't interactive:
+
+```cshtml
+Razor Page
+
+
+
+
+
+@functions {
+ [BindProperty(SupportsGet=true)]
+ public int InitialValue { get; set; }
+}
+```
+
+For more information, see .
+
+> [!IMPORTANT]
+> The use of a layout page (`_Layout.cshtml`) with a [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) for a component is required to control `` content, such as the page's title ( component) and other head elements ( component). For more information, see .
+
+## Component namespaces
+
+When using a custom folder to hold the project's Razor components, add the namespace representing the folder to either the page/view or to the `_ViewImports.cshtml` file. In the following example:
+
+* Components are stored in the `Components` folder of the project.
+* The `{APP NAMESPACE}` placeholder is the project's namespace. `Components` represents the name of the folder.
+
+```cshtml
+@using {APP NAMESPACE}.Components
+```
+
+The `_ViewImports.cshtml` file is located in the `Pages` folder of a Razor Pages app or the `Views` folder of an MVC app.
+
+For more information, see .
+
+:::zone-end
+
+## Persist prerendered state
+
+Without persisting prerendered state, state used during prerendering is lost and must be recreated when the app is fully loaded. If any state is setup asynchronously, the UI may flicker as the prerendered UI is replaced with temporary placeholders and then fully rendered again.
+
+To solve these problems, Blazor supports persisting state in a prerendered page using the [Persist Component State Tag Helper](xref:mvc/views/tag-helpers/builtin-th/persist-component-state-tag-helper). Add the Tag Helper's tag, ` `, inside the closing `` tag.
+
+`Pages/_Layout.cshtml`:
+
+```cshtml
+
+ ...
+
+
+
+```
+
+Decide what state to persist using the service. [`PersistentComponentState.RegisterOnPersisting`](xref:Microsoft.AspNetCore.Components.PersistentComponentState.RegisterOnPersisting%2A) registers a callback to persist the component state before the app is paused. The state is retrieved when the application resumes.
+
+The following example is an updated version of the `FetchData` component in a hosted Blazor WebAssembly app based on the Blazor project template. The `WeatherForecastPreserveState` component persists weather forecast state during prerendering and then retrieves the state to initialize the component. The [Persist Component State Tag Helper](xref:mvc/views/tag-helpers/builtin-th/persist-component-state-tag-helper) persists the component state after all component invocations.
+
+`Pages/WeatherForecastPreserveState.razor`:
+
+```razor
+@page "/weather-forecast-preserve-state"
+@implements IDisposable
+@using BlazorSample.Shared
+@inject IWeatherForecastService WeatherForecastService
+@inject PersistentComponentState ApplicationState
+
+Weather Forecast
+
+Weather forecast
+
+This component demonstrates fetching data from the server.
+
+@if (forecasts == null)
+{
+ Loading...
+}
+else
+{
+
+
+
+ Date
+ Temp. (C)
+ Temp. (F)
+ Summary
+
+
+
+ @foreach (var forecast in forecasts)
+ {
+
+ @forecast.Date.ToShortDateString()
+ @forecast.TemperatureC
+ @forecast.TemperatureF
+ @forecast.Summary
+
+ }
+
+
+}
+
+@code {
+ private WeatherForecast[] forecasts = Array.Empty();
+ private PersistingComponentStateSubscription persistingSubscription;
+
+ protected override async Task OnInitializedAsync()
+ {
+ persistingSubscription =
+ ApplicationState.RegisterOnPersisting(PersistForecasts);
+
+ if (!ApplicationState.TryTakeFromJson(
+ "fetchdata", out var restored))
+ {
+ forecasts =
+ await WeatherForecastService.GetForecastAsync(DateTime.Now);
+ }
+ else
+ {
+ forecasts = restored!;
+ }
+ }
+
+ private Task PersistForecasts()
+ {
+ ApplicationState.PersistAsJson("fetchdata", forecasts);
+
+ return Task.CompletedTask;
+ }
+
+ void IDisposable.Dispose()
+ {
+ persistingSubscription.Dispose();
+ }
+}
+```
+
+By initializing components with the same state used during prerendering, any expensive initialization steps are only executed once. The rendered UI also matches the prerendered UI, so no flicker occurs in the browser.
+
+The persisted prerendered state is transferred to the client, where it's used to restore the component state. [ASP.NET Core Data Protection](xref:security/data-protection/introduction) ensures that the data is transferred securely in Blazor Server apps. For prerendering in a hosted Blazor WebAssembly app, the data is exposed to the browser and must not contain sensitive, private information.
+
+:::zone pivot="webassembly"
+
+## Additional Blazor WebAssembly resources
+
+* [State management: Handle prerendering](xref:blazor/state-management#handle-prerendering)
+* [Prerendering support with assembly lazy loading](xref:blazor/webassembly-lazy-load-assemblies#lazy-load-assemblies-in-a-hosted-blazor-webassembly-solution)
+* Razor component lifecycle subjects that pertain to prerendering
+ * [Component initialization (`OnInitialized{Async}`)](xref:blazor/components/lifecycle#component-initialization-oninitializedasync)
+ * [After component render (`OnAfterRender{Async}`)](xref:blazor/components/lifecycle#after-component-render-onafterrenderasync)
+ * [Stateful reconnection after prerendering](xref:blazor/components/lifecycle#stateful-reconnection-after-prerendering): Although the content in the section focuses on Blazor Server and stateful SignalR *reconnection*, the scenario for prerendering in hosted Blazor WebAssembly apps () involves similar conditions and approaches to prevent executing developer code twice. To preserve state during the execution of initialization code while prerendering, see *Persist prerendered state* section of this article.
+ * [Prerendering with JavaScript interop](xref:blazor/components/lifecycle#prerendering-with-javascript-interop)
+* Authentication and authorization subjects that pertain to prerendering
+ * [General aspects](xref:blazor/security/index#aspnet-core-blazor-authentication-and-authorization)
+ * [Prerendering with authentication](xref:blazor/security/webassembly/additional-scenarios#prerendering-with-authentication)
+* [Host and deploy: Blazor WebAssembly](xref:blazor/host-and-deploy/webassembly)
+
+:::zone-end
+
+:::zone pivot="server"
+
+## Prerendered state size and SignalR message size limit
+
+A large prerendered state size may exceed the SignalR circuit message size limit, which results in the following:
+
+* The SignalR circuit fails to initialize with an error on the client: :::no-loc text="Circuit host not initialized.":::
+* The reconnection UI on the client appears when the circuit fails. Recovery isn't possible.
+
+To resolve the problem, use ***either*** of the following approaches:
+
+* Reduce the amount of data that you are putting into the prerendered state.
+* Increase the [SignalR message size limit](xref:blazor/fundamentals/signalr#server-side-circuit-handler-options). ***WARNING***: Increasing the limit may increase the risk of Denial of Service (DoS) attacks.
+
+## Additional Blazor Server resources
+
+* [State management: Handle prerendering](xref:blazor/state-management#handle-prerendering)
+* Razor component lifecycle subjects that pertain to prerendering
+ * [Component initialization (`OnInitialized{Async}`)](xref:blazor/components/lifecycle#component-initialization-oninitializedasync)
+ * [After component render (`OnAfterRender{Async}`)](xref:blazor/components/lifecycle#after-component-render-onafterrenderasync)
+ * [Stateful reconnection after prerendering](xref:blazor/components/lifecycle#stateful-reconnection-after-prerendering)
+ * [Prerendering with JavaScript interop](xref:blazor/components/lifecycle#prerendering-with-javascript-interop)
+* [Authentication and authorization: General aspects](xref:blazor/security/index#aspnet-core-blazor-authentication-and-authorization)
+* [Handle Errors: Prerendering](xref:blazor/fundamentals/handle-errors#prerendering)
+* [Host and deploy: Blazor Server](xref:blazor/host-and-deploy/server)
+* [Threat mitigation: Cross-site scripting (XSS)](xref:blazor/security/server/interactive-server-side-rendering#cross-site-scripting-xss)
+
+:::zone-end
+
+:::moniker-end
+
+:::moniker range=">= aspnetcore-5.0 < aspnetcore-6.0"
+
+:::zone pivot="webassembly"
+
+Razor components can be integrated into Razor Pages and MVC apps in a hosted Blazor WebAssembly [solution](xref:blazor/tooling#visual-studio-solution-file-sln). When the page or view is rendered, components can be prerendered at the same time.
+
+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.
+
+## Solution configuration
+
+### Prerendering configuration
+
+To set up prerendering for a hosted Blazor WebAssembly app:
+
+1. Host the Blazor WebAssembly app in an ASP.NET Core app. A standalone Blazor WebAssembly app can be added to an ASP.NET Core solution, or you can use a hosted Blazor WebAssembly app created from the [Blazor WebAssembly project template](xref:blazor/tooling) with the hosted option:
+
+ * Visual Studio: In the **Additional information** dialog, select the **ASP.NET Core Hosted** checkbox when creating the Blazor WebAssembly app. In this article's examples, the solution is named `BlazorHosted`.
+ * Visual Studio Code/.NET CLI command shell: `dotnet new blazorwasm -ho` (use the `-ho|--hosted` option). Use the `-o|--output {LOCATION}` option to create a folder for the solution and set the solution's project namespaces. In this article's examples, the solution is named `BlazorHosted` (`dotnet new blazorwasm -ho -o BlazorHosted`).
+
+ For the examples in this article, the client project's namespace is `BlazorHosted.Client`, and the server project's namespace is `BlazorHosted.Server`.
+
+1. **Delete** the `wwwroot/index.html` file from the Blazor WebAssembly **:::no-loc text="Client":::** project.
+
+1. In the **:::no-loc text="Client":::** project, **delete** the following line in `Program.cs`:
+
+ ```diff
+ - builder.RootComponents.Add("#app");
+ ```
+
+1. Add a `Pages/_Host.cshtml` file to the **:::no-loc text="Server":::** project's `Pages` folder. You can obtain a `_Host.cshtml` file from a project created from the Blazor Server template with the `dotnet new blazorserver -o BlazorServer` command in a command shell (the `-o BlazorServer` option creates a folder for the project). After placing the `Pages/_Host.cshtml` file into the **:::no-loc text="Server":::** project of the hosted Blazor WebAssembly solution, make the following changes to the file:
+
+ * Provide an [`@using`](xref:mvc/views/razor#using) directive for the **:::no-loc text="Client":::** project (for example, `@using BlazorHosted.Client`).
+ * Update the stylesheet links to point to the WebAssembly project's stylesheets. In the following example, the client project's namespace is `BlazorHosted.Client`:
+
+ ```diff
+ -
+ -
+ +
+ +
+ ```
+
+ > [!NOTE]
+ > Leave the ` ` element that requests the Bootstrap stylesheet (`css/bootstrap/bootstrap.min.css`) in place.
+
+ * Update the `render-mode` of the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) to prerender the root `App` component with :
+
+ ```diff
+ -
+ +
+ ```
+
+ * Update the Blazor script source to use the client-side Blazor WebAssembly script:
+
+ ```diff
+ -
+ +
+ ```
+
+1. In `Startup.Configure` of the **:::no-loc text="Server":::** project, change the fallback from the `index.html` file to the `_Host.cshtml` page.
+
+ `Startup.cs`:
+
+ ```diff
+ - endpoints.MapFallbackToFile("index.html");
+ + endpoints.MapFallbackToPage("/_Host");
+ ```
+
+1. If the **:::no-loc text="Client":::** and **:::no-loc text="Server":::** projects use one or more common services during prerendering, factor the service registrations into a method that can be called from both projects. For more information, see .
+
+1. Run the **:::no-loc text="Server":::** project. The hosted Blazor WebAssembly app is prerendered by the **:::no-loc text="Server":::** project for clients.
+
+### Configuration for embedding Razor components into pages and views
+
+The following sections and examples in this article for embedding Razor components of the client Blazor WebAssembly app into pages and views of the server app require additional configuration.
+
+Use a default Razor Pages or MVC layout file in the **:::no-loc text="Server":::** project. The **:::no-loc text="Server":::** project must have the following files and folders.
+
+Razor Pages:
+
+* `Pages/Shared/_Layout.cshtml`
+* `Pages/_ViewImports.cshtml`
+* `Pages/_ViewStart.cshtml`
+
+MVC:
+
+* `Views/Shared/_Layout.cshtml`
+* `Views/_ViewImports.cshtml`
+* `Views/_ViewStart.cshtml`
+
+Obtain the preceding files from an app created from the Razor Pages or MVC project template. For more information, see or .
+
+Update the namespaces in the imported `_ViewImports.cshtml` file to match those in use by the **:::no-loc text="Server":::** project receiving the files.
+
+Update the imported layout file (`_Layout.cshtml`) to include the **:::no-loc text="Client":::** project's styles. In the following example, the **:::no-loc text="Client":::** project's namespace is `BlazorHosted.Client`. The `` element can be updated at the same time.
+
+`Pages/Shared/_Layout.cshtml` (Razor Pages) or `Views/Shared/_Layout.cshtml` (MVC):
+
+```diff
+
+
+
+- @ViewData["Title"] - DonorProject
++ @ViewData["Title"] - BlazorHosted
+
+
++
++
+
+```
+
+The imported layout contains `Home` and `Privacy` navigation links. To make the `Home` link point to the hosted Blazor WebAssembly app, change the hyperlink:
+
+```diff
+- Home
++ Home
+```
+
+In an MVC layout file:
+
+```diff
+- Home
++ Home
+```
+
+To make the `Privacy` link lead to a privacy page, add a privacy page to the **:::no-loc text="Server":::** project.
+
+`Pages/Privacy.cshtml` in the **:::no-loc text="Server":::** project:
+
+```cshtml
+@page
+@model BlazorHosted.Server.Pages.PrivacyModel
+@{
+}
+
+Privacy Policy
+```
+
+If an MVC-based privacy view is preferred, create a privacy view in the **:::no-loc text="Server":::** project.
+
+`View/Home/Privacy.cshtml`:
+
+```cshtml
+@{
+ ViewData["Title"] = "Privacy Policy";
+}
+
+@ViewData["Title"]
+```
+
+In the `Home` controller, return the view.
+
+`Controllers/HomeController.cs`:
+
+```csharp
+public IActionResult Privacy()
+{
+ return View();
+}
+```
+
+Import static assets to the **:::no-loc text="Server":::** project from the donor project's `wwwroot` folder:
+
+* `wwwroot/css` folder and contents
+* `wwwroot/js` folder and contents
+* `wwwroot/lib` folder and contents
+
+If the donor project is created from an ASP.NET Core project template and the files aren't modified, you can copy the entire `wwwroot` folder from the donor project into the **:::no-loc text="Server":::** project and remove the :::no-loc text="favicon"::: icon file.
+
+> [!WARNING]
+> Avoid placing the static asset into both the **:::no-loc text="Client":::** and **:::no-loc text="Server":::** `wwwroot` folders. If the same file is present in both folders, an exception is thrown because the static asset in each folder shares the same web root path. Therefore, host a static asset in either `wwwroot` folder, not both.
+
+## Render components in a page or view with the Component Tag Helper
+
+After [configuring the solution](#solution-configuration), including the [additional configuration](#configuration-for-embedding-razor-components-into-pages-and-views), the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) supports two render modes for rendering a component from a Blazor WebAssembly app in a page or view:
+
+*
+*
+
+In the following Razor Pages example, the `Counter` component is rendered in a page. To make the component interactive, the Blazor WebAssembly script is included in the page's [render section](xref:mvc/views/layout#sections). To avoid using the full namespace for the `Counter` component with the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) (`{ASSEMBLY NAME}.Pages.Counter`), add an [`@using`](xref:mvc/views/razor#using) directive for the client project's `Pages` namespace. In the following example, the **:::no-loc text="Client":::** project's namespace is `BlazorHosted.Client`.
+
+In the **:::no-loc text="Server":::** project, `Pages/RazorPagesCounter1.cshtml`:
+
+```cshtml
+@page
+@using BlazorHosted.Client.Pages
+
+
+
+@section Scripts {
+
+}
+```
+
+Run the **:::no-loc text="Server":::** project. Navigate to the Razor page at `/razorpagescounter1`. The prerendered `Counter` component is embedded in the page.
+
+ configures whether the component:
+
+* Is prerendered into the page.
+* Is rendered as static HTML on the page or if it includes the necessary information to bootstrap a Blazor app from the user agent.
+
+For more information on the Component Tag Helper, including passing parameters and configuration, see .
+
+Additional work might be required depending on the static resources that components use and how layout pages are organized in an app. Typically, scripts are added to a page or view's `Scripts` render section and stylesheets are added to the layout's `` element content.
+
+## Render components in a page or view with a CSS selector
+
+After [configuring the solution](#solution-configuration), including the [additional configuration](#configuration-for-embedding-razor-components-into-pages-and-views), add root components to the **:::no-loc text="Client":::** project of a hosted Blazor WebAssembly solution in `Program.cs`. In the following example, the `Counter` component is declared as a root component with a CSS selector that selects the element with the `id` that matches `counter-component`. In the following example, the **:::no-loc text="Client":::** project's namespace is `BlazorHosted.Client`.
+
+In `Program.cs` of the **:::no-loc text="Client":::** project, add the namespace for the project's Razor components to the top of the file:
+
+```csharp
+using BlazorHosted.Client.Pages;
+```
+
+After the `builder` is established in `Program.cs`, add the `Counter` component as a root component:
+
+```csharp
+builder.RootComponents.Add("#counter-component");
+```
+
+In the following Razor Pages example, the `Counter` component is rendered in a page. To make the component interactive, the Blazor WebAssembly script is included in the page's [render section](xref:mvc/views/layout#sections).
+
+In the **:::no-loc text="Server":::** project, `Pages/RazorPagesCounter2.cshtml`:
+
+```cshtml
+@page
+
+Loading...
+
+@section Scripts {
+
+}
+```
+
+Run the **:::no-loc text="Server":::** project. Navigate to the Razor page at `/razorpagescounter2`. The prerendered `Counter` component is embedded in the page.
+
+Additional work might be required depending on the static resources that components use and how layout pages are organized in an app. Typically, scripts are added to a page or view's `Scripts` render section and stylesheets are added to the layout's `` element content.
+
+> [!NOTE]
+> The preceding example throws a if a Blazor WebAssembly app is prerendered and integrated into a Razor Pages or MVC app **simultaneously** with a CSS selector. Navigating to one of the **:::no-loc text="Client":::** project's Razor components throws the following exception:
+>
+> > Microsoft.JSInterop.JSException: Could not find any element matching selector '#counter-component'.
+>
+> This is normal behavior because prerendering and integrating a Blazor WebAssembly app with routable Razor components is incompatible with the use of CSS selectors.
+
+:::zone-end
+
+:::zone pivot="server"
+
+Razor components can be integrated into Razor Pages and MVC apps. When the page or view is rendered, components can be prerendered at the same time.
+
+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.
+
+After [configuring the project](#configuration), use the guidance in the following sections depending on the project's requirements:
+
+* Routable components: For components that are directly routable from user requests. Follow this guidance when visitors should be able to make an HTTP request in their browser for a component with an [`@page`](xref:mvc/views/razor#page) directive.
+ * [Use routable components in a Razor Pages app](#use-routable-components-in-a-razor-pages-app)
+ * [Use routable components in an MVC app](#use-routable-components-in-an-mvc-app)
+* [Render components from a page or view](#render-components-from-a-page-or-view): For components that aren't directly routable from user requests. Follow this guidance when the app embeds components into existing pages and views with the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper).
+
+## Configuration
+
+An existing Razor Pages or MVC app can integrate Razor components into pages and views:
+
+1. In the project's layout file:
+
+ * Add the following ` ` tag to the `` element in `Pages/Shared/_Layout.cshtml` (Razor Pages) or `Views/Shared/_Layout.cshtml` (MVC):
+
+ ```html
+
+ ```
+
+ The `href` value (the *app base path*) in the preceding example assumes that the app resides at the root URL path (`/`). If the app is a sub-application, follow the guidance in the *App base path* section of the article.
+
+ * Add a `
+
+ @await RenderSectionAsync("Scripts", required: false)
+
+ ```
+
+ The framework adds the `blazor.server.js` script to the app. There's no need to manually add a `blazor.server.js` script file to the app.
+
+1. Add an imports file to the root folder of the project with the following content. Change the `{APP NAMESPACE}` placeholder to the namespace of the project.
+
+ `_Imports.razor`:
+
+ ```razor
+ @using System.Net.Http
+ @using Microsoft.AspNetCore.Authorization
+ @using Microsoft.AspNetCore.Components.Authorization
+ @using Microsoft.AspNetCore.Components.Forms
+ @using Microsoft.AspNetCore.Components.Routing
+ @using Microsoft.AspNetCore.Components.Web
+ @using Microsoft.JSInterop
+ @using {APP NAMESPACE}
+ ```
+
+1. Register the Blazor Server service in `Startup.ConfigureServices`.
+
+ In `Startup.cs`:
+
+ ```csharp
+ services.AddServerSideBlazor();
+ ```
+
+1. Add the Blazor Hub endpoint to the endpoints (`app.UseEndpoints`) of `Startup.Configure`.
+
+ `Startup.cs`:
+
+ ```csharp
+ endpoints.MapBlazorHub();
+ ```
+
+1. Integrate components into any page or view. For example, add a `Counter` component to the project's `Shared` folder.
+
+ `Pages/Shared/Counter.razor` (Razor Pages) or `Views/Shared/Counter.razor` (MVC):
+
+ ```razor
+ Counter
+
+ Current count: @currentCount
+
+ Click me
+
+ @code {
+ private int currentCount = 0;
+
+ private void IncrementCount()
+ {
+ currentCount++;
+ }
+ }
+ ```
+
+ **Razor Pages**:
+
+ In the project's `Index` page of a Razor Pages app, add the `Counter` component's namespace and embed the component into the page. When the `Index` page loads, the `Counter` component is prerendered in the page. In the following example, replace the `{APP NAMESPACE}` placeholder with the project's namespace.
+
+ `Pages/Index.cshtml`:
+
+ ```cshtml
+ @page
+ @using {APP NAMESPACE}.Pages.Shared
+ @model IndexModel
+ @{
+ ViewData["Title"] = "Home page";
+ }
+
+
+
+
+ ```
+
+ In the preceding example, replace the `{APP NAMESPACE}` placeholder with the app's namespace.
+
+ **MVC**:
+
+ In the project's `Index` view of an MVC app, add the `Counter` component's namespace and embed the component into the view. When the `Index` view loads, the `Counter` component is prerendered in the page. In the following example, replace the `{APP NAMESPACE}` placeholder with the project's namespace.
+
+ `Views/Home/Index.cshtml`:
+
+ ```cshtml
+ @using {APP NAMESPACE}.Views.Shared
+ @{
+ ViewData["Title"] = "Home Page";
+ }
+
+
+
+
+ ```
+
+For more information, see the [Render components from a page or view](#render-components-from-a-page-or-view) section.
+
+## Use routable components in a Razor Pages app
+
+*This section pertains to adding components that are directly routable from user requests.*
+
+To support routable Razor components in Razor Pages apps:
+
+1. Follow the guidance in the [Configuration](#configuration) section.
+
+1. Add an `App` component to the project root with the following content.
+
+ `App.razor`:
+
+ ```razor
+ @using Microsoft.AspNetCore.Components.Routing
+
+
+
+
+
+
+ Page not found
+ Sorry, but there's nothing here!
+
+
+ ```
+
+ [!INCLUDE[](~/blazor/includes/prefer-exact-matches.md)]
+
+1. Add a `_Host` page to the project with the following content.
+
+ `Pages/_Host.cshtml`:
+
+ ```cshtml
+ @page "/blazor"
+ @{
+ Layout = "_Layout";
+ }
+
+
+
+
+ ```
+
+ Components use the shared `_Layout.cshtml` file for their layout.
+
+ configures whether the `App` component:
+
+ * Is prerendered into the page.
+ * Is rendered as static HTML on the page or if it includes the necessary information to bootstrap a Blazor app from the user agent.
+
+ For more information on the Component Tag Helper, including passing parameters and configuration, see .
+
+1. In the `Startup.Configure` endpoints of `Startup.cs`, add a low-priority route for the `_Host` page as the last endpoint:
+
+ ```csharp
+ endpoints.MapFallbackToPage("/_Host");
+ ```
+
+ The following example shows the added line in a typical app's endpoint configuration:
+
+ ```csharp
+ app.UseEndpoints(endpoints =>
+ {
+ endpoints.MapRazorPages();
+ endpoints.MapBlazorHub();
+ endpoints.MapFallbackToPage("/_Host");
+ });
+ ```
+
+1. Add routable components to the project.
+
+ `Pages/RoutableCounter.razor`:
+
+ ```razor
+ @page "/routable-counter"
+
+ Routable Counter
+
+ Current count: @currentCount
+
+ Click me
+
+ @code {
+ private int currentCount = 0;
+
+ private void IncrementCount()
+ {
+ currentCount++;
+ }
+ }
+ ```
+
+1. Run the project and navigate to the routable `RoutableCounter` component at `/routable-counter`.
+
+For more information on namespaces, see the [Component namespaces](#component-namespaces) section.
+
+## Use routable components in an MVC app
+
+*This section pertains to adding components that are directly routable from user requests.*
+
+To support routable Razor components in MVC apps:
+
+1. Follow the guidance in the [Configuration](#configuration) section.
+
+1. Add an `App` component to the project root with the following content.
+
+ `App.razor`:
+
+ ```razor
+ @using Microsoft.AspNetCore.Components.Routing
+
+
+
+
+
+
+ Page not found
+ Sorry, but there's nothing here!
+
+
+ ```
+
+ [!INCLUDE[](~/blazor/includes/prefer-exact-matches.md)]
+
+1. Add a `_Host` view to the project with the following content.
+
+ `Views/Home/_Host.cshtml`:
+
+ ```cshtml
+ @{
+ Layout = "_Layout";
+ }
+
+
+
+
+ ```
+
+ Components use the shared `_Layout.cshtml` file for their layout.
+
+ configures whether the `App` component:
+
+ * Is prerendered into the page.
+ * Is rendered as static HTML on the page or if it includes the necessary information to bootstrap a Blazor app from the user agent.
+
+ For more information on the Component Tag Helper, including passing parameters and configuration, see .
+
+1. Add an action to the Home controller.
+
+ `Controllers/HomeController.cs`:
+
+ ```csharp
+ public IActionResult Blazor()
+ {
+ return View("_Host");
+ }
+ ```
+
+1. In the `Startup.Configure` endpoints of `Startup.cs`, add a low-priority route for the controller action that returns the `_Host` view:
+
+ ```csharp
+ endpoints.MapFallbackToController("Blazor", "Home");
+ ```
+
+ The following example shows the added line in a typical app's endpoint configuration:
+
+ ```csharp
+ app.UseEndpoints(endpoints =>
+ {
+ endpoints.MapControllerRoute(
+ name: "default",
+ pattern: "{controller=Home}/{action=Index}/{id?}");
+ endpoints.MapBlazorHub();
+ endpoints.MapFallbackToController("Blazor", "Home");
+ });
+ ```
+
+1. Add routable components to the project.
+
+ `Pages/RoutableCounter.razor`:
+
+ ```razor
+ @page "/routable-counter"
+
+ Routable Counter
+
+ Current count: @currentCount
+
+ Click me
+
+ @code {
+ private int currentCount = 0;
+
+ private void IncrementCount()
+ {
+ currentCount++;
+ }
+ }
+ ```
+
+1. Run the project and navigate to the routable `RoutableCounter` component at `/routable-counter`.
+
+For more information on namespaces, see the [Component namespaces](#component-namespaces) section.
+
+## Render components from a page or view
+
+*This section pertains to adding components to pages or views, where the components aren't directly routable from user requests.*
+
+To render a component from a page or view, use the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper).
+
+### Render stateful interactive components
+
+Stateful interactive components can be added to a Razor page or view.
+
+When the page or view renders:
+
+* The component is prerendered with the page or view.
+* The initial component state used for prerendering is lost.
+* New component state is created when the SignalR connection is established.
+
+The following Razor page renders a `Counter` component:
+
+```cshtml
+My Razor Page
+
+
+
+@functions {
+ [BindProperty(SupportsGet=true)]
+ public int InitialValue { get; set; }
+}
+```
+
+For more information, see .
+
+### Render noninteractive components
+
+In the following Razor page, the `Counter` component is statically rendered with an initial value that's specified using a form. Since the component is statically rendered, the component isn't interactive:
+
+```cshtml
+My Razor Page
+
+
+
+
+
+@functions {
+ [BindProperty(SupportsGet=true)]
+ public int InitialValue { get; set; }
+}
+```
+
+For more information, see .
+
+## Component namespaces
+
+When using a custom folder to hold the project's Razor components, add the namespace representing the folder to either the page/view or to the `_ViewImports.cshtml` file. In the following example:
+
+* Components are stored in the `Components` folder of the project.
+* The `{APP NAMESPACE}` placeholder is the project's namespace. `Components` represents the name of the folder.
+
+```cshtml
+@using {APP NAMESPACE}.Components
+```
+
+The `_ViewImports.cshtml` file is located in the `Pages` folder of a Razor Pages app or the `Views` folder of an MVC app.
+
+For more information, see .
+
+:::zone-end
+
+:::zone pivot="webassembly"
+
+## Additional Blazor WebAssembly resources
+
+* [State management: Handle prerendering](xref:blazor/state-management#handle-prerendering)
+* [Prerendering support with assembly lazy loading](xref:blazor/webassembly-lazy-load-assemblies#lazy-load-assemblies-in-a-hosted-blazor-webassembly-solution)
+* Razor component lifecycle subjects that pertain to prerendering
+ * [Component initialization (`OnInitialized{Async}`)](xref:blazor/components/lifecycle#component-initialization-oninitializedasync)
+ * [After component render (`OnAfterRender{Async}`)](xref:blazor/components/lifecycle#after-component-render-onafterrenderasync)
+ * [Stateful reconnection after prerendering](xref:blazor/components/lifecycle#stateful-reconnection-after-prerendering): Although the content in the section focuses on Blazor Server and stateful SignalR *reconnection*, the scenario for prerendering in hosted Blazor WebAssembly apps () involves similar conditions and approaches to prevent executing developer code twice. To preserve state during the execution of initialization code while prerendering, see *Persist prerendered state* section of this article.
+ * [Prerendering with JavaScript interop](xref:blazor/components/lifecycle#prerendering-with-javascript-interop)
+* Authentication and authorization subjects that pertain to prerendering
+ * [General aspects](xref:blazor/security/index#aspnet-core-blazor-authentication-and-authorization)
+ * [Prerendering with authentication](xref:blazor/security/webassembly/additional-scenarios#prerendering-with-authentication)
+* [Host and deploy: Blazor WebAssembly](xref:blazor/host-and-deploy/webassembly)
+
+:::zone-end
+
+:::zone pivot="server"
+
+## Prerendered state size and SignalR message size limit
+
+A large prerendered state size may exceed the SignalR circuit message size limit, which results in the following:
+
+* The SignalR circuit fails to initialize with an error on the client: :::no-loc text="Circuit host not initialized.":::
+* The reconnection UI on the client appears when the circuit fails. Recovery isn't possible.
+
+To resolve the problem, use ***either*** of the following approaches:
+
+* Reduce the amount of data that you are putting into the prerendered state.
+* Increase the [SignalR message size limit](xref:blazor/fundamentals/signalr#server-side-circuit-handler-options). ***WARNING***: Increasing the limit may increase the risk of Denial of Service (DoS) attacks.
+
+## Additional Blazor Server resources
+
+* [State management: Handle prerendering](xref:blazor/state-management#handle-prerendering)
+* Razor component lifecycle subjects that pertain to prerendering
+ * [Component initialization (`OnInitialized{Async}`)](xref:blazor/components/lifecycle#component-initialization-oninitializedasync)
+ * [After component render (`OnAfterRender{Async}`)](xref:blazor/components/lifecycle#after-component-render-onafterrenderasync)
+ * [Stateful reconnection after prerendering](xref:blazor/components/lifecycle#stateful-reconnection-after-prerendering)
+ * [Prerendering with JavaScript interop](xref:blazor/components/lifecycle#prerendering-with-javascript-interop)
+* [Authentication and authorization: General aspects](xref:blazor/security/index#aspnet-core-blazor-authentication-and-authorization)
+* [Handle Errors: Prerendering](xref:blazor/fundamentals/handle-errors#prerendering)
+* [Host and deploy: Blazor Server](xref:blazor/host-and-deploy/server)
+* [Threat mitigation: Cross-site scripting (XSS)](xref:blazor/security/server/interactive-server-side-rendering#cross-site-scripting-xss)
+
+:::zone-end
+
+:::moniker-end
+
+:::moniker range="< aspnetcore-5.0"
+
+:::zone pivot="webassembly"
+
+Integrating Razor components into Razor Pages and MVC apps in a hosted Blazor WebAssembly [solution](xref:blazor/tooling#visual-studio-solution-file-sln) is supported in ASP.NET Core in .NET 5 or later. Select a .NET 5 or later version of this article.
+
+:::zone-end
+
+:::zone pivot="server"
+
+Razor components can be integrated into Razor Pages and MVC apps. When the page or view is rendered, components can be prerendered at the same time.
+
+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.
+
+After [configuring the project](#configuration), use the guidance in the following sections depending on the project's requirements:
+
+* Routable components: For components that are directly routable from user requests. Follow this guidance when visitors should be able to make an HTTP request in their browser for a component with an [`@page`](xref:mvc/views/razor#page) directive.
+ * [Use routable components in a Razor Pages app](#use-routable-components-in-a-razor-pages-app)
+ * [Use routable components in an MVC app](#use-routable-components-in-an-mvc-app)
+* [Render components from a page or view](#render-components-from-a-page-or-view): For components that aren't directly routable from user requests. Follow this guidance when the app embeds components into existing pages and views with the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper).
+
+## Configuration
+
+An existing Razor Pages or MVC app can integrate Razor components into pages and views:
+
+1. In the project's layout file:
+
+ * Add the following ` ` tag to the `` element in `Pages/Shared/_Layout.cshtml` (Razor Pages) or `Views/Shared/_Layout.cshtml` (MVC):
+
+ ```diff
+ +
+ ```
+
+ The `href` value (the *app base path*) in the preceding example assumes that the app resides at the root URL path (`/`). If the app is a sub-application, follow the guidance in the *App base path* section of the article.
+
+ * Add a `
+
+ @await RenderSectionAsync("Scripts", required: false)
+
+ ```
+
+ The framework adds the `blazor.server.js` script to the app. There's no need to manually add a `blazor.server.js` script file to the app.
+
+1. Add an imports file to the root folder of the project with the following content. Change the `{APP NAMESPACE}` placeholder to the namespace of the project.
+
+ `_Imports.razor`:
+
+ ```razor
+ @using System.Net.Http
+ @using Microsoft.AspNetCore.Authorization
+ @using Microsoft.AspNetCore.Components.Authorization
+ @using Microsoft.AspNetCore.Components.Forms
+ @using Microsoft.AspNetCore.Components.Routing
+ @using Microsoft.AspNetCore.Components.Web
+ @using Microsoft.JSInterop
+ @using {APP NAMESPACE}
+ ```
+
+1. Register the Blazor Server service in `Startup.ConfigureServices`.
+
+ `Startup.cs`:
+
+ ```csharp
+ services.AddServerSideBlazor();
+ ```
+
+1. Add the Blazor Hub endpoint to the endpoints (`app.UseEndpoints`) of `Startup.Configure`.
+
+ `Startup.cs`:
+
+ ```csharp
+ endpoints.MapBlazorHub();
+ ```
+
+1. Integrate components into any page or view. For example, add a `Counter` component to the project's `Shared` folder.
+
+ `Pages/Shared/Counter.razor` (Razor Pages) or `Views/Shared/Counter.razor` (MVC):
+
+ ```razor
+ Counter
+
+ Current count: @currentCount
+
+ Click me
+
+ @code {
+ private int currentCount = 0;
+
+ private void IncrementCount()
+ {
+ currentCount++;
+ }
+ }
+ ```
+
+ **Razor Pages**:
+
+ In the project's `Index` page of a Razor Pages app, add the `Counter` component's namespace and embed the component into the page. When the `Index` page loads, the `Counter` component is prerendered in the page. In the following example, replace the `{APP NAMESPACE}` placeholder with the project's namespace.
+
+ `Pages/Index.cshtml`:
+
+ ```cshtml
+ @page
+ @using {APP NAMESPACE}.Pages.Shared
+ @model IndexModel
+ @{
+ ViewData["Title"] = "Home page";
+ }
+
+
+
+
+ ```
+
+ In the preceding example, replace the `{APP NAMESPACE}` placeholder with the app's namespace.
+
+ **MVC**:
+
+ In the project's `Index` view of an MVC app, add the `Counter` component's namespace and embed the component into the view. When the `Index` view loads, the `Counter` component is prerendered in the page. In the following example, replace the `{APP NAMESPACE}` placeholder with the project's namespace.
+
+ `Views/Home/Index.cshtml`:
+
+ ```cshtml
+ @using {APP NAMESPACE}.Views.Shared
+ @{
+ ViewData["Title"] = "Home Page";
+ }
+
+
+
+
+ ```
+
+For more information, see the [Render components from a page or view](#render-components-from-a-page-or-view) section.
+
+## Use routable components in a Razor Pages app
+
+*This section pertains to adding components that are directly routable from user requests.*
+
+To support routable Razor components in Razor Pages apps:
+
+1. Follow the guidance in the [Configuration](#configuration) section.
+
+1. Add an `App` component to the project root with the following content.
+
+ `App.razor`:
+
+ ```razor
+ @using Microsoft.AspNetCore.Components.Routing
+
+
+
+
+
+
+ Page not found
+ Sorry, but there's nothing here!
+
+
+ ```
+
+1. Add a `_Host` page to the project with the following content.
+
+ `Pages/_Host.cshtml`:
+
+ ```cshtml
+ @page "/blazor"
+ @{
+ Layout = "_Layout";
+ }
+
+
+
+
+ ```
+
+ Components use the shared `_Layout.cshtml` file for their layout.
+
+ configures whether the `App` component:
+
+ * Is prerendered into the page.
+ * Is rendered as static HTML on the page or if it includes the necessary information to bootstrap a Blazor app from the user agent.
+
+ For more information on the Component Tag Helper, including passing parameters and configuration, see .
+
+1. In the `Startup.Configure` endpoints of `Startup.cs`, add a low-priority route for the `_Host` page as the last endpoint:
+
+ ```csharp
+ endpoints.MapFallbackToPage("/_Host");
+ ```
+
+ The following example shows the added line in a typical app's endpoint configuration:
+
+ ```csharp
+ app.UseEndpoints(endpoints =>
+ {
+ endpoints.MapRazorPages();
+ endpoints.MapBlazorHub();
+ endpoints.MapFallbackToPage("/_Host");
+ });
+ ```
+
+1. Add routable components to the project.
+
+ `Pages/RoutableCounter.razor`:
+
+ ```razor
+ @page "/routable-counter"
+
+ Routable Counter
+
+ Current count: @currentCount
+
+ Click me
+
+ @code {
+ private int currentCount = 0;
+
+ private void IncrementCount()
+ {
+ currentCount++;
+ }
+ }
+ ```
+
+1. Run the project and navigate to the routable `RoutableCounter` component at `/routable-counter`.
+
+For more information on namespaces, see the [Component namespaces](#component-namespaces) section.
+
+## Use routable components in an MVC app
+
+*This section pertains to adding components that are directly routable from user requests.*
+
+To support routable Razor components in MVC apps:
+
+1. Follow the guidance in the [Configuration](#configuration) section.
+
+1. Add an `App` component to the project root with the following content.
+
+ `App.razor`:
+
+ ```razor
+ @using Microsoft.AspNetCore.Components.Routing
+
+
+
+
+
+
+ Page not found
+ Sorry, but there's nothing here!
+
+
+ ```
+
+1. Add a `_Host` view to the project with the following content.
+
+ `Views/Home/_Host.cshtml`:
+
+ ```cshtml
+ @{
+ Layout = "_Layout";
+ }
+
+
+
+
+ ```
+
+ Components use the shared `_Layout.cshtml` file for their layout.
+
+ configures whether the `App` component:
+
+ * Is prerendered into the page.
+ * Is rendered as static HTML on the page or if it includes the necessary information to bootstrap a Blazor app from the user agent.
+
+ For more information on the Component Tag Helper, including passing parameters and configuration, see .
+
+1. Add an action to the Home controller.
+
+ `Controllers/HomeController.cs`:
+
+ ```csharp
+ public IActionResult Blazor()
+ {
+ return View("_Host");
+ }
+ ```
+
+1. In the `Startup.Configure` endpoints of `Startup.cs`, add a low-priority route for the controller action that returns the `_Host` view:
+
+ ```csharp
+ endpoints.MapFallbackToController("Blazor", "Home");
+ ```
+
+ The following example shows the added line in a typical app's endpoint configuration:
+
+ ```csharp
+ app.UseEndpoints(endpoints =>
+ {
+ endpoints.MapControllerRoute(
+ name: "default",
+ pattern: "{controller=Home}/{action=Index}/{id?}");
+ endpoints.MapBlazorHub();
+ endpoints.MapFallbackToController("Blazor", "Home");
+ });
+ ```
+
+1. Add routable components to the project.
+
+ `Pages/RoutableCounter.razor`:
+
+ ```razor
+ @page "/routable-counter"
+
+ Routable Counter
+
+ Current count: @currentCount
+
+ Click me
+
+ @code {
+ private int currentCount = 0;
+
+ private void IncrementCount()
+ {
+ currentCount++;
+ }
+ }
+ ```
+
+1. Run the project and navigate to the routable `RoutableCounter` component at `/routable-counter`.
+
+For more information on namespaces, see the [Component namespaces](#component-namespaces) section.
+
+## Render components from a page or view
+
+*This section pertains to adding components to pages or views, where the components aren't directly routable from user requests.*
+
+To render a component from a page or view, use the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper).
+
+### Render stateful interactive components
+
+Stateful interactive components can be added to a Razor page or view.
+
+When the page or view renders:
+
+* The component is prerendered with the page or view.
+* The initial component state used for prerendering is lost.
+* New component state is created when the SignalR connection is established.
+
+The following Razor page renders a `Counter` component:
+
+```cshtml
+My Razor Page
+
+
+
+@functions {
+ [BindProperty(SupportsGet=true)]
+ public int InitialValue { get; set; }
+}
+```
+
+For more information, see .
+
+### Render noninteractive components
+
+In the following Razor page, the `Counter` component is statically rendered with an initial value that's specified using a form. Since the component is statically rendered, the component isn't interactive:
+
+```cshtml
+My Razor Page
+
+
+
+
+
+@functions {
+ [BindProperty(SupportsGet=true)]
+ public int InitialValue { get; set; }
+}
+```
+
+For more information, see .
+
+## Component namespaces
+
+When using a custom folder to hold the project's Razor components, add the namespace representing the folder to either the page/view or to the `_ViewImports.cshtml` file. In the following example:
+
+* Components are stored in the `Components` folder of the project.
+* The `{APP NAMESPACE}` placeholder is the project's namespace. `Components` represents the name of the folder.
+
+```cshtml
+@using {APP NAMESPACE}.Components
+```
+
+The `_ViewImports.cshtml` file is located in the `Pages` folder of a Razor Pages app or the `Views` folder of an MVC app.
+
+For more information, see .
+
+## Prerendered state size and SignalR message size limit
+
+A large prerendered state size may exceed the SignalR circuit message size limit, which results in the following:
+
+* The SignalR circuit fails to initialize with an error on the client: :::no-loc text="Circuit host not initialized.":::
+* The reconnection UI on the client appears when the circuit fails. Recovery isn't possible.
+
+To resolve the problem, use ***either*** of the following approaches:
+
+* Reduce the amount of data that you are putting into the prerendered state.
+* Increase the [SignalR message size limit](xref:blazor/fundamentals/signalr#server-side-circuit-handler-options). ***WARNING***: Increasing the limit may increase the risk of Denial of Service (DoS) attacks.
+
+## Additional Blazor Server resources
+
+* [State management: Handle prerendering](xref:blazor/state-management#handle-prerendering)
+* Razor component lifecycle subjects that pertain to prerendering
+ * [Component initialization (`OnInitialized{Async}`)](xref:blazor/components/lifecycle#component-initialization-oninitializedasync)
+ * [After component render (`OnAfterRender{Async}`)](xref:blazor/components/lifecycle#after-component-render-onafterrenderasync)
+ * [Stateful reconnection after prerendering](xref:blazor/components/lifecycle#stateful-reconnection-after-prerendering)
+ * [Prerendering with JavaScript interop](xref:blazor/components/lifecycle#prerendering-with-javascript-interop)
+* [Authentication and authorization: General aspects](xref:blazor/security/index#aspnet-core-blazor-authentication-and-authorization)
+* [Handle Errors: Prerendering](xref:blazor/fundamentals/handle-errors#prerendering)
+* [Host and deploy: Blazor Server](xref:blazor/host-and-deploy/server)
+* [Threat mitigation: Cross-site scripting (XSS)](xref:blazor/security/server/interactive-server-side-rendering#cross-site-scripting-xss)
+
+:::zone-end
+
+:::moniker-end
diff --git a/aspnetcore/blazor/components/layouts.md b/aspnetcore/blazor/components/layouts.md
index 75e250372aac..f643e5460f57 100644
--- a/aspnetcore/blazor/components/layouts.md
+++ b/aspnetcore/blazor/components/layouts.md
@@ -385,18 +385,8 @@ The following rendered HTML markup is produced by the preceding nested layout. E
## Share a Razor Pages layout with integrated components
-:::moniker range=">= aspnetcore-8.0"
-
When routable components are integrated into a Razor Pages app, the app's shared layout can be used with the components. For more information, see .
-:::moniker-end
-
-:::moniker range="< aspnetcore-8.0"
-
-When routable components are integrated into a Razor Pages app, the app's shared layout can be used with the components. For more information, see .
-
-:::moniker-end
-
:::moniker range=">= aspnetcore-8.0"
## Sections
diff --git a/aspnetcore/blazor/components/lifecycle.md b/aspnetcore/blazor/components/lifecycle.md
index 39df76e2d641..d992b943709b 100644
--- a/aspnetcore/blazor/components/lifecycle.md
+++ b/aspnetcore/blazor/components/lifecycle.md
@@ -206,7 +206,7 @@ To prevent developer code in from running twice when prerendering, see the [Stateful reconnection after prerendering](#stateful-reconnection-after-prerendering) section. Although the content in the section focuses on Blazor Server and stateful SignalR *reconnection*, the scenario for prerendering in hosted Blazor WebAssembly solutions () involves similar conditions and approaches to prevent executing developer code twice. To preserve state during the execution of initialization code while prerendering, see .
+To prevent developer code in from running twice when prerendering, see the [Stateful reconnection after prerendering](#stateful-reconnection-after-prerendering) section. Although the content in the section focuses on Blazor Server and stateful SignalR *reconnection*, the scenario for prerendering in hosted Blazor WebAssembly solutions () involves similar conditions and approaches to prevent executing developer code twice. To preserve state during the execution of initialization code while prerendering, see .
:::moniker-end
@@ -612,7 +612,7 @@ The content in this section focuses on Blazor Web Apps and stateful SignalR *rec
:::moniker range="< aspnetcore-8.0"
-Although the content in this section focuses on Blazor Server and stateful SignalR *reconnection*, the scenario for prerendering in hosted Blazor WebAssembly solutions () involves similar conditions and approaches to prevent executing developer code twice. To preserve state during the execution of initialization code while prerendering, see .
+Although the content in this section focuses on Blazor Server and stateful SignalR *reconnection*, the scenario for prerendering in hosted Blazor WebAssembly solutions () involves similar conditions and approaches to prevent executing developer code twice. To preserve state during the execution of initialization code while prerendering, see .
:::moniker-end
diff --git a/aspnetcore/blazor/components/prerendering-and-integration.md b/aspnetcore/blazor/components/prerendering-and-integration.md
deleted file mode 100644
index 833dc82a8960..000000000000
--- a/aspnetcore/blazor/components/prerendering-and-integration.md
+++ /dev/null
@@ -1,3065 +0,0 @@
----
-title: Prerender and integrate ASP.NET Core Razor components
-author: guardrex
-description: Learn about Razor component integration scenarios for Blazor apps, including prerendering of Razor components on the server.
-monikerRange: '>= aspnetcore-3.1 < aspnetcore-8.0'
-ms.author: riande
-ms.custom: mvc
-ms.date: 02/09/2024
-uid: blazor/components/prerendering-and-integration
-zone_pivot_groups: blazor-hosting-models
----
-# Prerender and integrate ASP.NET Core Razor components
-
-:::moniker range="< aspnetcore-7.0"
-
-> [!NOTE]
-> This isn't the latest version of this article. For the latest version of this article, see the [.NET 7 version](?view=aspnetcore-7.0&preserve-view=true).
-
-:::moniker-end
-
-This article explains Razor component integration scenarios for Blazor apps, including prerendering of Razor components on the server.
-
-> [!IMPORTANT]
-> Framework changes across ASP.NET Core releases led to different sets of instructions in this article. Before using this article's guidance, confirm that the document version selector at the top of this article matches the version of ASP.NET Core that you intend to use for your app.
-
-:::moniker range=">= aspnetcore-7.0"
-
-:::zone pivot="webassembly"
-
-Razor components can be integrated into Razor Pages and MVC apps in a hosted Blazor WebAssembly [solution](xref:blazor/tooling#visual-studio-solution-file-sln). When the page or view is rendered, components can be prerendered at the same time.
-
-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.
-
-## Solution configuration
-
-### Prerendering configuration
-
-To set up prerendering for a hosted Blazor WebAssembly app:
-
-1. Host the Blazor WebAssembly app in an ASP.NET Core app. A standalone Blazor WebAssembly app can be added to an ASP.NET Core solution, or you can use a hosted Blazor WebAssembly app created from the [Blazor WebAssembly project template](xref:blazor/tooling) with the hosted option:
-
- * Visual Studio: In the **Additional information** dialog, select the **ASP.NET Core Hosted** checkbox when creating the Blazor WebAssembly app. In this article's examples, the solution is named `BlazorHosted`.
- * Visual Studio Code/.NET CLI command shell: `dotnet new blazorwasm -ho` (use the `-ho|--hosted` option). Use the `-o|--output {LOCATION}` option to create a folder for the solution and set the solution's project namespaces. In this article's examples, the solution is named `BlazorHosted` (`dotnet new blazorwasm -ho -o BlazorHosted`).
-
- For the examples in this article, the hosted solution's name (assembly name) is `BlazorHosted`. The client project's namespace is `BlazorHosted.Client`, and the server project's namespace is `BlazorHosted.Server`.
-
-1. **Delete** the `wwwroot/index.html` file from the Blazor WebAssembly **:::no-loc text="Client":::** project.
-
-1. In the **:::no-loc text="Client":::** project, **delete** the following lines in `Program.cs`:
-
- ```diff
- - builder.RootComponents.Add("#app");
- - builder.RootComponents.Add("head::after");
- ```
-
-1. Add `_Host.cshtml` file to the **:::no-loc text="Server":::** project's `Pages` folder. You can obtain the files from a project created from the Blazor Server template using Visual Studio or using the .NET CLI with the `dotnet new blazorserver -o BlazorServer` command in a command shell (the `-o BlazorServer` option creates a folder for the project). After placing the files into the **:::no-loc text="Server":::** project's `Pages` folder, make the following changes to the files.
-
- Make the following changes to the `_Host.cshtml` file:
-
- * Update the `Pages` namespace at the top of the file to match the namespace of the **:::no-loc text="Server":::** app's pages. The `{APP NAMESPACE}` placeholder in the following example represents the namespace of the donor app's pages that provided the `_Host.cshtml` file:
-
- Delete:
-
- ```diff
- - @namespace {APP NAMESPACE}.Pages
- ```
-
- Add:
-
- ```razor
- @namespace BlazorHosted.Server.Pages
- ```
-
- * Add an [`@using`](xref:mvc/views/razor#using) directive for the **:::no-loc text="Client":::** project at the top of the file:
-
- ```razor
- @using BlazorHosted.Client
- ```
-
- * Update the stylesheet links to point to the WebAssembly project's stylesheets. In the following example, the client project's namespace is `BlazorHosted.Client`. The `{APP NAMESPACE}` placeholder represents the namespace of the donor app that provided the `_Host.cshtml` file. Update the Component Tag Helper (`` tag) for the `HeadOutlet` component to prerender the component.
-
- Delete:
-
- ```diff
- -
- -
- -
- ```
-
- Add:
-
- ```cshtml
-
-
-
- ```
-
- > [!NOTE]
- > Leave the ` ` element that requests the Bootstrap stylesheet (`css/bootstrap/bootstrap.min.css`) in place.
-
- * Update the Blazor script source to use the client-side Blazor WebAssembly script:
-
- Delete:
-
- ```diff
- -
- ```
-
- Add:
-
- ```html
-
- ```
-
- * Update the `render-mode` of the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) to prerender the root `App` component with :
-
- Delete:
-
- ```diff
- -
- ```
-
- Add:
-
- ```cshtml
-
- ```
-
- > [!IMPORTANT]
- > Prerendering isn't supported for authentication endpoints (`/authentication/` path segment). For more information, see .
-
-1. In the `Program.cs` file of the **:::no-loc text="Server":::** project, change the fallback endpoint from the `index.html` file to the `_Host.cshtml` page:
-
- Delete:
-
- ```diff
- - app.MapFallbackToFile("index.html");
- ```
-
- Add:
-
- ```csharp
- app.MapFallbackToPage("/_Host");
- ```
-
-1. If the **:::no-loc text="Client":::** and **:::no-loc text="Server":::** projects use one or more common services during prerendering, factor the service registrations into a method that can be called from both projects. For more information, see .
-
-1. Run the **:::no-loc text="Server":::** project. The hosted Blazor WebAssembly app is prerendered by the **:::no-loc text="Server":::** project for clients.
-
-### Configuration for embedding Razor components into pages and views
-
-The following sections and examples for embedding Razor components from the **:::no-loc text="Client":::** Blazor WebAssembly app into pages and views of the server app require additional configuration.
-
-The **:::no-loc text="Server":::** project must have the following files and folders.
-
-Razor Pages:
-
-* `Pages/Shared/_Layout.cshtml`
-* `Pages/Shared/_Layout.cshtml.css`
-* `Pages/_ViewImports.cshtml`
-* `Pages/_ViewStart.cshtml`
-
-MVC:
-
-* `Views/Shared/_Layout.cshtml`
-* `Views/Shared/_Layout.cshtml.css`
-* `Views/_ViewImports.cshtml`
-* `Views/_ViewStart.cshtml`
-
-The preceding files can be obtained by generating an app from the ASP.NET Core project templates using:
-
-* Visual Studio's new project creation tools.
-* Opening a command shell and executing `dotnet new webapp -o {PROJECT NAME}` (Razor Pages) or `dotnet new mvc -o {PROJECT NAME}` (MVC). The option `-o|--output` with a value for the `{PROJECT NAME}` placeholder provides a name for the app and creates a folder for the app.
-
-Update the namespaces in the imported `_ViewImports.cshtml` file to match those in use by the **:::no-loc text="Server":::** project receiving the files.
-
-`Pages/_ViewImports.cshtml` (Razor Pages):
-
-```razor
-@using BlazorHosted.Server
-@namespace BlazorHosted.Server.Pages
-@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
-```
-
-`Views/_ViewImports.cshtml` (MVC):
-
-```razor
-@using BlazorHosted.Server
-@using BlazorHosted.Server.Models
-@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
-```
-
-Update the imported layout file, which is `Pages/Shared/_Layout.cshtml` for Razor Pages or `Views/Shared/_Layout.cshtml` for MVC.
-
-First, delete the title and the stylesheet from the donor project, which is `RPDonor.styles.css` in the following example. The `{PROJECT NAME}` placeholder represents the donor project's app name.
-
-```diff
-- @ViewData["Title"] - {PROJECT NAME}
--
-```
-
-Include the **:::no-loc text="Client":::** project's styles in the layout file. In the following example, the **:::no-loc text="Client":::** project's namespace is `BlazorHosted.Client`. The `` element can be updated at the same time.
-
-Place the following lines in the `` content of the layout file:
-
-```cshtml
-@ViewData["Title"] - BlazorHosted
-
-
-
-```
-
-The imported layout contains two `Home` (`Index` page) and `Privacy` navigation links. To make the `Home` links point to the hosted Blazor WebAssembly app, change the hyperlinks:
-
-```diff
-- {PROJECT NAME}
-+ BlazorHosted
-```
-
-```diff
-- Home
-+ Home
-```
-
-In an MVC layout file:
-
-```diff
-- {PROJECT NAME}
-+ BlazorHosted
-```
-
-```diff
-- Home
-+ Home
-```
-
-Update the `` element's app name. The following example uses the app name `BlazorHosted`:
-
-```diff
-- © {DATE} - {DONOR NAME} - Privacy
-+ © {DATE} - BlazorHosted - Privacy
-```
-
-In the preceding example, the `{DATE}` placeholder represents the copyright date in an app generated from the Razor Pages or MVC project template.
-
-To make the `Privacy` link lead to a privacy page (Razor Pages), add a privacy page to the **:::no-loc text="Server":::** project.
-
-`Pages/Privacy.cshtml` in the **:::no-loc text="Server":::** project:
-
-```cshtml
-@page
-@model PrivacyModel
-@{
- ViewData["Title"] = "Privacy Policy";
-}
-@ViewData["Title"]
-
-Use this page to detail your site's privacy policy.
-```
-
-For an MVC-based privacy view, create a privacy view in the **:::no-loc text="Server":::** project.
-
-`View/Home/Privacy.cshtml` in the **:::no-loc text="Server":::** project:
-
-```cshtml
-@{
- ViewData["Title"] = "Privacy Policy";
-}
-@ViewData["Title"]
-
-Use this page to detail your site's privacy policy.
-```
-
-In the `Home` controller of the MVC app, return the view.
-
-Add the following code to `Controllers/HomeController.cs`:
-
-```csharp
-public IActionResult Privacy()
-{
- return View();
-}
-```
-
-If you import files from a donor app, be sure to update any namespaces in the files to match that of the **:::no-loc text="Server":::** project (for example, `BlazorHosted.Server`).
-
-Import static assets to the **:::no-loc text="Server":::** project from the donor project's `wwwroot` folder:
-
-* `wwwroot/css` folder and contents
-* `wwwroot/js` folder and contents
-* `wwwroot/lib` folder and contents
-
-If the donor project is created from an ASP.NET Core project template and the files aren't modified, you can copy the entire `wwwroot` folder from the donor project into the **:::no-loc text="Server":::** project and remove the :::no-loc text="favicon"::: icon file.
-
-> [!WARNING]
-> Avoid placing the static asset into both the **:::no-loc text="Client":::** and **:::no-loc text="Server":::** `wwwroot` folders. If the same file is present in both folders, an exception is thrown because the static assets share the same web root path. Therefore, host a static asset in either of the `wwwroot` folders, not both.
-
-After adopting the preceding configuration, embed Razor components into pages or views of the **:::no-loc text="Server":::** project. Use the guidance in the following sections of this article:
-
-* *Render components in a page or view with the Component Tag Helper*
-* *Render components in a page or view with a CSS selector*
-
-## Render components in a page or view with the Component Tag Helper
-
-After [configuring the solution](#solution-configuration), including the [additional configuration](#configuration-for-embedding-razor-components-into-pages-and-views), the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) supports two render modes for rendering a component from a Blazor WebAssembly app in a page or view:
-
-*
-*
-
-In the following Razor Pages example, the `Counter` component is rendered in a page. To make the component interactive, the Blazor WebAssembly script is included in the page's [render section](xref:mvc/views/layout#sections). To avoid using the full namespace for the `Counter` component with the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) (`{ASSEMBLY NAME}.Pages.Counter`), add an [`@using`](xref:mvc/views/razor#using) directive for the client project's `Pages` namespace. In the following example, the **:::no-loc text="Client":::** project's namespace is `BlazorHosted.Client`.
-
-In the **:::no-loc text="Server":::** project, `Pages/RazorPagesCounter1.cshtml`:
-
-```cshtml
-@page
-@using BlazorHosted.Client.Pages
-
-
-
-@section Scripts {
-
-}
-```
-
-Run the **:::no-loc text="Server":::** project. Navigate to the Razor page at `/razorpagescounter1`. The prerendered `Counter` component is embedded in the page.
-
- configures whether the component:
-
-* Is prerendered into the page.
-* Is rendered as static HTML on the page or if it includes the necessary information to bootstrap a Blazor app from the user agent.
-
-For more information on the Component Tag Helper, including passing parameters and configuration, see .
-
-Additional work might be required depending on the static resources that components use and how layout pages are organized in an app. Typically, scripts are added to a page or view's `Scripts` render section and stylesheets are added to the layout's `` element content.
-
-### Set child content through a render fragment
-
-The [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) doesn't support receiving a [`RenderFragment` delegate for child content](xref:blazor/components/index#child-content-render-fragments) (for example, `param-ChildContent="..."`). We recommend creating a Razor component (`.razor`) that references the component you want to render with the child content you want to pass and then invoke the Razor component from the page or view.
-
-### Ensure that top-level prerendered components aren't trimmed out on publish
-
-If a [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) directly references a component from a library that's subject to trimming on publish, the component might be trimmed out during publish because there are no references to it from client-side app code. As a result, the component isn't prerendered, leaving a blank spot in the output. If this occurs, instruct the trimmer to preserve the library component by adding a [`DynamicDependency` attribute](xref:System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute) to any class in the client-side app. To preserve a component called `SomeLibraryComponentToBePreserved`, add the following to any component:
-
-```razor
-@using System.Diagnostics.CodeAnalysis
-@attribute [DynamicDependency(DynamicallyAccessedMemberTypes.All,
- typeof(SomeLibraryComponentToBePreserved))]
-```
-
-The preceding approach usually isn't required because the app usually prerenders its components (which are not trimmed), which in turn references components from libraries (causing them also not to be trimmed). Only use `DynamicDependency` explicitly for prerendering a library component directly when the library is subject to trimming.
-
-## Render components in a page or view with a CSS selector
-
-After [configuring the solution](#solution-configuration), including the [additional configuration](#configuration-for-embedding-razor-components-into-pages-and-views), add root components to the **:::no-loc text="Client":::** project of a hosted Blazor WebAssembly solution in the `Program.cs` file. In the following example, the `Counter` component is declared as a root component with a CSS selector that selects the element with the `id` that matches `counter-component`. In the following example, the **:::no-loc text="Client":::** project's namespace is `BlazorHosted.Client`.
-
-In `Program.cs` file of the **:::no-loc text="Client":::** project, add the namespace for the project's Razor components to the top of the file:
-
-```csharp
-using BlazorHosted.Client.Pages;
-```
-
-After the `builder` is established in `Program.cs`, add the `Counter` component as a root component:
-
-```csharp
-builder.RootComponents.Add("#counter-component");
-```
-
-In the following Razor Pages example, the `Counter` component is rendered in a page. To make the component interactive, the Blazor WebAssembly script is included in the page's [render section](xref:mvc/views/layout#sections).
-
-In the **:::no-loc text="Server":::** project, `Pages/RazorPagesCounter2.cshtml`:
-
-```cshtml
-@page
-
-Loading...
-
-@section Scripts {
-
-}
-```
-
-Run the **:::no-loc text="Server":::** project. Navigate to the Razor page at `/razorpagescounter2`. The prerendered `Counter` component is embedded in the page.
-
-Additional work might be required depending on the static resources that components use and how layout pages are organized in an app. Typically, scripts are added to a page or view's `Scripts` render section and stylesheets are added to the layout's `` element content.
-
-> [!NOTE]
-> The preceding example throws a if a Blazor WebAssembly app is prerendered and integrated into a Razor Pages or MVC app **simultaneously** with the use of a CSS selector. Navigating to one of the **:::no-loc text="Client":::** project's Razor components or navigating to a page or view of the **:::no-loc text="Server":::** with an embedded component throws one or more .
->
-> This is normal behavior because prerendering and integrating a Blazor WebAssembly app with routable Razor components is incompatible with the use of CSS selectors.
->
-> If you've been working with the examples in the preceding sections and just wish to see the CSS selector work in your sample app, comment out the specification of the `App` root component of the **:::no-loc text="Client":::** project's `Program.cs` file:
->
-> ```diff
-> - builder.RootComponents.Add("#app");
-> + //builder.RootComponents.Add("#app");
-> ```
->
-> Navigate to the page or view with the embedded Razor component that uses a CSS selector (for example, `/razorpagescounter2` of the preceding example). The page or view loads with the embedded component, and the embedded component functions as expected.
-
-:::zone-end
-
-:::zone pivot="server"
-
-Razor components can be integrated into Razor Pages and MVC apps. When the page or view is rendered, components can be prerendered at the same time.
-
-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.
-
-After [configuring the project](#configuration), use the guidance in the following sections depending on the project's requirements:
-
-* For components that are directly routable from user requests. Follow this guidance when visitors should be able to make an HTTP request in their browser for a component with an [`@page`](xref:mvc/views/razor#page) directive.
- * [Use routable components in a Razor Pages app](#use-routable-components-in-a-razor-pages-app)
- * [Use routable components in an MVC app](#use-routable-components-in-an-mvc-app)
-* For components that aren't directly routable from user requests, see the [Render components from a page or view](#render-components-from-a-page-or-view) section. Follow this guidance when the app embeds components into existing pages and views with the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper).
-
-## Configuration
-
-Use the following guidance to integrate Razor components into pages and views of an existing Razor Pages or MVC app.
-
-1. Add an imports file to the root folder of the project with the following content. Change the `{APP NAMESPACE}` placeholder to the namespace of the project.
-
- `_Imports.razor`:
-
- ```razor
- @using System.Net.Http
- @using Microsoft.AspNetCore.Authorization
- @using Microsoft.AspNetCore.Components.Authorization
- @using Microsoft.AspNetCore.Components.Forms
- @using Microsoft.AspNetCore.Components.Routing
- @using Microsoft.AspNetCore.Components.Web
- @using Microsoft.AspNetCore.Components.Web.Virtualization
- @using Microsoft.JSInterop
- @using {APP NAMESPACE}
- ```
-
-1. In the project's layout file (`Pages/Shared/_Layout.cshtml` in Razor Pages apps or `Views/Shared/_Layout.cshtml` in MVC apps):
-
- * Add the following ` ` tag and component Tag Helper to the `` element:
-
- ```cshtml
-
-
- ```
-
- The `href` value (the *app base path*) in the preceding example assumes that the app resides at the root URL path (`/`). If the app is a sub-application, follow the guidance in the *App base path* section of the article.
-
- The component is used to render head (``) content for page titles ( component) and other head elements ( component) set by Razor components. For more information, see .
-
- * Add a `
- ```
-
- The framework adds the `blazor.server.js` script to the app. There's no need to manually add a `blazor.server.js` script file to the app.
-
- > [!NOTE]
- > Typically, the layout loads via a `_ViewStart.cshtml` file.
-
-1. Register the Blazor Server services in `Program.cs` where services are registered:
-
- ```csharp
- builder.Services.AddServerSideBlazor();
- ```
-
-1. Add the Blazor Hub endpoint to the endpoints of `Program.cs` where routes are mapped. Place the following line after the call to `MapRazorPages` (Razor Pages) or `MapControllerRoute` (MVC):
-
- ```csharp
- app.MapBlazorHub();
- ```
-
-1. Integrate components into any page or view. For example, add a `Counter` component to the project's `Shared` folder.
-
- `Pages/Shared/Counter.razor` (Razor Pages) or `Views/Shared/Counter.razor` (MVC):
-
- ```razor
- Counter
-
- Current count: @currentCount
-
- Click me
-
- @code {
- private int currentCount = 0;
-
- private void IncrementCount()
- {
- currentCount++;
- }
- }
- ```
-
- **Razor Pages**:
-
- In the project's `Index` page of a Razor Pages app, add the `Counter` component's namespace and embed the component into the page. When the `Index` page loads, the `Counter` component is prerendered in the page. In the following example, replace the `{APP NAMESPACE}` placeholder with the project's namespace.
-
- `Pages/Index.cshtml`:
-
- ```cshtml
- @page
- @using {APP NAMESPACE}.Pages.Shared
- @model IndexModel
- @{
- ViewData["Title"] = "Home page";
- }
-
-
- ```
-
- **MVC**:
-
- In the project's `Index` view of an MVC app, add the `Counter` component's namespace and embed the component into the view. When the `Index` view loads, the `Counter` component is prerendered in the page. In the following example, replace the `{APP NAMESPACE}` placeholder with the project's namespace.
-
- `Views/Home/Index.cshtml`:
-
- ```cshtml
- @using {APP NAMESPACE}.Views.Shared
- @{
- ViewData["Title"] = "Home Page";
- }
-
-
- ```
-
-For more information, see the [Render components from a page or view](#render-components-from-a-page-or-view) section.
-
-## Use routable components in a Razor Pages app
-
-*This section pertains to adding components that are directly routable from user requests.*
-
-To support routable Razor components in Razor Pages apps:
-
-1. Follow the guidance in the [Configuration](#configuration) section.
-
-1. Add an `App` component to the project root with the following content.
-
- `App.razor`:
-
- ```razor
- @using Microsoft.AspNetCore.Components.Routing
-
-
-
-
-
-
- Not found
- Sorry, there's nothing at this address.
-
-
- ```
-
-1. Add a `_Host` page to the project with the following content. Replace the `{APP NAMESPACE}` placeholder with the app's namespace.
-
- `Pages/_Host.cshtml`:
-
- ```cshtml
- @page
- @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
-
-
- ```
-
- > [!NOTE]
- > The preceding example assumes that the component and Blazor script (`_framework/blazor.server.js`) are rendered by the app's layout. For more information, see the [Configuration](#configuration) section.
-
- configures whether the `App` component:
-
- * Is prerendered into the page.
- * Is rendered as static HTML on the page or if it includes the necessary information to bootstrap a Blazor app from the user agent.
-
- For more information on the Component Tag Helper, including passing parameters and configuration, see .
-
-1. In the `Program.cs` endpoints, add a low-priority route for the `_Host` page as the last endpoint:
-
- ```csharp
- app.MapFallbackToPage("/_Host");
- ```
-
-1. Add routable components to the project. The following example is a `RoutableCounter` component based on the `Counter` component in the Blazor project templates.
-
- `Pages/RoutableCounter.razor`:
-
- ```razor
- @page "/routable-counter"
-
- Routable Counter
-
- Routable Counter
-
- Current count: @currentCount
-
- Click me
-
- @code {
- private int currentCount = 0;
-
- private void IncrementCount()
- {
- currentCount++;
- }
- }
- ```
-
-1. Run the project and navigate to the routable `RoutableCounter` component at `/routable-counter`.
-
-For more information on namespaces, see the [Component namespaces](#component-namespaces) section.
-
-## Use routable components in an MVC app
-
-*This section pertains to adding components that are directly routable from user requests.*
-
-To support routable Razor components in MVC apps:
-
-1. Follow the guidance in the [Configuration](#configuration) section.
-
-1. Add an `App` component to the project root with the following content.
-
- `App.razor`:
-
- ```razor
- @using Microsoft.AspNetCore.Components.Routing
-
-
-
-
-
-
- Not found
- Sorry, there's nothing at this address.
-
-
- ```
-
-1. Add a `_Host` view to the project with the following content. Replace the `{APP NAMESPACE}` placeholder with the app's namespace.
-
- `Views/Home/_Host.cshtml`:
-
- ```cshtml
- @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
-
-
- ```
-
- > [!NOTE]
- > The preceding example assumes that the component and Blazor script (`_framework/blazor.server.js`) are rendered by the app's layout. For more information, see the [Configuration](#configuration) section.
-
- configures whether the `App` component:
-
- * Is prerendered into the page.
- * Is rendered as static HTML on the page or if it includes the necessary information to bootstrap a Blazor app from the user agent.
-
- For more information on the Component Tag Helper, including passing parameters and configuration, see .
-
-1. Add an action to the Home controller.
-
- `Controllers/HomeController.cs`:
-
- ```csharp
- public IActionResult Blazor()
- {
- return View("_Host");
- }
- ```
-
-1. In the `Program.cs` endpoints, add a low-priority route for the controller action that returns the `_Host` view:
-
- ```csharp
- app.MapFallbackToController("Blazor", "Home");
- ```
-
-1. Create a `Pages` folder in the MVC app and add routable components. The following example is a `RoutableCounter` component based on the `Counter` component in the Blazor project templates.
-
- `Pages/RoutableCounter.razor`:
-
- ```razor
- @page "/routable-counter"
-
- Routable Counter
-
- Routable Counter
-
- Current count: @currentCount
-
- Click me
-
- @code {
- private int currentCount = 0;
-
- private void IncrementCount()
- {
- currentCount++;
- }
- }
- ```
-
-1. Run the project and navigate to the routable `RoutableCounter` component at `/routable-counter`.
-
-For more information on namespaces, see the [Component namespaces](#component-namespaces) section.
-
-## Render components from a page or view
-
-*This section pertains to adding components to pages or views, where the components aren't directly routable from user requests.*
-
-To render a component from a page or view, use the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper).
-
-### Render stateful interactive components
-
-Stateful interactive components can be added to a Razor page or view.
-
-When the page or view renders:
-
-* The component is prerendered with the page or view.
-* The initial component state used for prerendering is lost.
-* New component state is created when the SignalR connection is established.
-
-The following Razor page renders a `Counter` component:
-
-```cshtml
-Razor Page
-
-
-
-@functions {
- [BindProperty(SupportsGet=true)]
- public int InitialValue { get; set; }
-}
-```
-
-For more information, see .
-
-### Render noninteractive components
-
-In the following Razor page, the `Counter` component is statically rendered with an initial value that's specified using a form. Since the component is statically rendered, the component isn't interactive:
-
-```cshtml
-Razor Page
-
-
-
-
-
-@functions {
- [BindProperty(SupportsGet=true)]
- public int InitialValue { get; set; }
-}
-```
-
-For more information, see .
-
-## Component namespaces
-
-When using a custom folder to hold the project's Razor components, add the namespace representing the folder to either the page/view or to the `_ViewImports.cshtml` file. In the following example:
-
-* Components are stored in the `Components` folder of the project.
-* The `{APP NAMESPACE}` placeholder is the project's namespace. `Components` represents the name of the folder.
-
-```cshtml
-@using {APP NAMESPACE}.Components
-```
-
-The `_ViewImports.cshtml` file is located in the `Pages` folder of a Razor Pages app or the `Views` folder of an MVC app.
-
-For more information, see .
-
-:::zone-end
-
-## Persist prerendered state
-
-Without persisting prerendered state, state used during prerendering is lost and must be recreated when the app is fully loaded. If any state is setup asynchronously, the UI may flicker as the prerendered UI is replaced with temporary placeholders and then fully rendered again.
-
-To persist state for prerendered components, use the [Persist Component State Tag Helper](xref:mvc/views/tag-helpers/builtin-th/persist-component-state-tag-helper) ([reference source](https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.TagHelpers/src/PersistComponentStateTagHelper.cs)). Add the Tag Helper's tag, ` `, inside the closing `` tag of the `_Host` page in an app that prerenders components.
-
-[!INCLUDE[](~/includes/aspnetcore-repo-ref-source-links.md)]
-
-In `Pages/_Host.cshtml` of Blazor apps that are either WebAssembly prerendered (`WebAssemblyPrerendered`) in a hosted Blazor WebAssembly app or `ServerPrerendered` in a Blazor Server app:
-
-```cshtml
-
- ...
-
-
-
-```
-
-Decide what state to persist using the service. [`PersistentComponentState.RegisterOnPersisting`](xref:Microsoft.AspNetCore.Components.PersistentComponentState.RegisterOnPersisting%2A) registers a callback to persist the component state before the app is paused. The state is retrieved when the application resumes.
-
-In the following example:
-
-* The `{TYPE}` placeholder represents the type of data to persist (for example, `WeatherForecast[]`).
-* The `{TOKEN}` placeholder is a state identifier string (for example, `fetchdata`).
-
-```razor
-@implements IDisposable
-@inject PersistentComponentState ApplicationState
-
-...
-
-@code {
- private {TYPE} data;
- private PersistingComponentStateSubscription persistingSubscription;
-
- protected override async Task OnInitializedAsync()
- {
- persistingSubscription =
- ApplicationState.RegisterOnPersisting(PersistData);
-
- if (!ApplicationState.TryTakeFromJson<{TYPE}>(
- "{TOKEN}", out var restored))
- {
- data = await ...;
- }
- else
- {
- data = restored!;
- }
- }
-
- private Task PersistData()
- {
- ApplicationState.PersistAsJson("{TOKEN}", data);
-
- return Task.CompletedTask;
- }
-
- void IDisposable.Dispose()
- {
- persistingSubscription.Dispose();
- }
-}
-```
-
-The following example is an updated version of the `FetchData` component in a hosted Blazor WebAssembly app based on the Blazor project template. The `WeatherForecastPreserveState` component persists weather forecast state during prerendering and then retrieves the state to initialize the component. The [Persist Component State Tag Helper](xref:mvc/views/tag-helpers/builtin-th/persist-component-state-tag-helper) persists the component state after all component invocations.
-
-`Pages/WeatherForecastPreserveState.razor`:
-
-```razor
-@page "/weather-forecast-preserve-state"
-@using BlazorSample.Shared
-@implements IDisposable
-@inject IWeatherForecastService WeatherForecastService
-@inject PersistentComponentState ApplicationState
-
-Weather Forecast
-
-Weather forecast
-
-This component demonstrates fetching data from the server.
-
-@if (forecasts == null)
-{
- Loading...
-}
-else
-{
-
-
-
- Date
- Temp. (C)
- Temp. (F)
- Summary
-
-
-
- @foreach (var forecast in forecasts)
- {
-
- @forecast.Date.ToShortDateString()
- @forecast.TemperatureC
- @forecast.TemperatureF
- @forecast.Summary
-
- }
-
-
-}
-
-@code {
- private WeatherForecast[] forecasts = Array.Empty();
- private PersistingComponentStateSubscription persistingSubscription;
-
- protected override async Task OnInitializedAsync()
- {
- persistingSubscription =
- ApplicationState.RegisterOnPersisting(PersistForecasts);
-
- if (!ApplicationState.TryTakeFromJson(
- "fetchdata", out var restored))
- {
- forecasts =
- await WeatherForecastService.GetForecastAsync(DateOnly.FromDateTime(DateTime.Now));
- }
- else
- {
- forecasts = restored!;
- }
- }
-
- private Task PersistForecasts()
- {
- ApplicationState.PersistAsJson("fetchdata", forecasts);
-
- return Task.CompletedTask;
- }
-
- void IDisposable.Dispose()
- {
- persistingSubscription.Dispose();
- }
-}
-```
-
-By initializing components with the same state used during prerendering, any expensive initialization steps are only executed once. The rendered UI also matches the prerendered UI, so no flicker occurs in the browser.
-
-The persisted prerendered state is transferred to the client, where it's used to restore the component state. [ASP.NET Core Data Protection](xref:security/data-protection/introduction) ensures that the data is transferred securely in Blazor Server apps. For prerendering in a hosted Blazor WebAssembly app, the data is exposed to the browser and must not contain sensitive, private information.
-
-:::zone pivot="webassembly"
-
-## Additional Blazor WebAssembly resources
-
-* [State management: Handle prerendering](xref:blazor/state-management#handle-prerendering)
-* [Prerendering support with assembly lazy loading](xref:blazor/webassembly-lazy-load-assemblies#lazy-load-assemblies-in-a-hosted-blazor-webassembly-solution)
-* Razor component lifecycle subjects that pertain to prerendering
- * [Component initialization (`OnInitialized{Async}`)](xref:blazor/components/lifecycle#component-initialization-oninitializedasync)
- * [After component render (`OnAfterRender{Async}`)](xref:blazor/components/lifecycle#after-component-render-onafterrenderasync)
- * [Stateful reconnection after prerendering](xref:blazor/components/lifecycle#stateful-reconnection-after-prerendering): Although the content in the section focuses on Blazor Server and stateful SignalR *reconnection*, the scenario for prerendering in hosted Blazor WebAssembly apps () involves similar conditions and approaches to prevent executing developer code twice. To preserve state during the execution of initialization code while prerendering, see *Persist prerendered state* section of this article.
- * [Prerendering with JavaScript interop](xref:blazor/components/lifecycle#prerendering-with-javascript-interop)
-* Authentication and authorization subjects that pertain to prerendering
- * [General aspects](xref:blazor/security/index)
- * [Prerendering with authentication in hosted Blazor WebAssembly apps](xref:blazor/security/webassembly/additional-scenarios#prerendering-with-authentication)
-* [Host and deploy: Blazor WebAssembly](xref:blazor/host-and-deploy/webassembly)
-* [Handle errors: Prerendering](xref:blazor/fundamentals/handle-errors#prerendering)
-* is executed *twice* when prerendering: [Handle asynchronous navigation events with `OnNavigateAsync`](xref:blazor/fundamentals/routing#handle-asynchronous-navigation-events-with-onnavigateasync)
-
-:::zone-end
-
-:::zone pivot="server"
-
-## Prerendered state size and SignalR message size limit
-
-A large prerendered state size may exceed the SignalR circuit message size limit, which results in the following:
-
-* The SignalR circuit fails to initialize with an error on the client: :::no-loc text="Circuit host not initialized.":::
-* The reconnection UI on the client appears when the circuit fails. Recovery isn't possible.
-
-To resolve the problem, use ***either*** of the following approaches:
-
-* Reduce the amount of data that you are putting into the prerendered state.
-* Increase the [SignalR message size limit](xref:blazor/fundamentals/signalr#server-side-circuit-handler-options). ***WARNING***: Increasing the limit may increase the risk of Denial of Service (DoS) attacks.
-
-## Additional Blazor Server resources
-
-* [State management: Handle prerendering](xref:blazor/state-management#handle-prerendering)
-* Razor component lifecycle subjects that pertain to prerendering
- * [Component initialization (`OnInitialized{Async}`)](xref:blazor/components/lifecycle#component-initialization-oninitializedasync)
- * [After component render (`OnAfterRender{Async}`)](xref:blazor/components/lifecycle#after-component-render-onafterrenderasync)
- * [Stateful reconnection after prerendering](xref:blazor/components/lifecycle#stateful-reconnection-after-prerendering)
- * [Prerendering with JavaScript interop](xref:blazor/components/lifecycle#prerendering-with-javascript-interop)
-* [Authentication and authorization: General aspects](xref:blazor/security/index#aspnet-core-blazor-authentication-and-authorization)
-* [Handle Errors: Prerendering](xref:blazor/fundamentals/handle-errors#prerendering)
-* [Host and deploy: Blazor Server](xref:blazor/host-and-deploy/server)
-* [Threat mitigation: Cross-site scripting (XSS)](xref:blazor/security/server/interactive-server-side-rendering#cross-site-scripting-xss)
-* is executed *twice* when prerendering: [Handle asynchronous navigation events with `OnNavigateAsync`](xref:blazor/fundamentals/routing#handle-asynchronous-navigation-events-with-onnavigateasync)
-
-:::zone-end
-
-:::moniker-end
-
-:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
-
-:::zone pivot="webassembly"
-
-Razor components can be integrated into Razor Pages and MVC apps in a hosted Blazor WebAssembly [solution](xref:blazor/tooling#visual-studio-solution-file-sln). When the page or view is rendered, components can be prerendered at the same time.
-
-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.
-
-## Solution configuration
-
-### Prerendering configuration
-
-To set up prerendering for a hosted Blazor WebAssembly app:
-
-1. Host the Blazor WebAssembly app in an ASP.NET Core app. A standalone Blazor WebAssembly app can be added to an ASP.NET Core solution, or you can use a hosted Blazor WebAssembly app created from the [Blazor WebAssembly project template](xref:blazor/tooling) with the hosted option:
-
- * Visual Studio: In the **Additional information** dialog, select the **ASP.NET Core Hosted** checkbox when creating the Blazor WebAssembly app. In this article's examples, the solution is named `BlazorHosted`.
- * Visual Studio Code/.NET CLI command shell: `dotnet new blazorwasm -ho` (use the `-ho|--hosted` option). Use the `-o|--output {LOCATION}` option to create a folder for the solution and set the solution's project namespaces. In this article's examples, the solution is named `BlazorHosted` (`dotnet new blazorwasm -ho -o BlazorHosted`).
-
- For the examples in this article, the client project's namespace is `BlazorHosted.Client`, and the server project's namespace is `BlazorHosted.Server`.
-
-1. **Delete** the `wwwroot/index.html` file from the Blazor WebAssembly **:::no-loc text="Client":::** project.
-
-1. In the **:::no-loc text="Client":::** project, **delete** the following lines in `Program.cs`:
-
- ```diff
- - builder.RootComponents.Add("#app");
- - builder.RootComponents.Add("head::after");
- ```
-
-1. Add `_Host.cshtml` and `_Layout.cshtml` files to the **:::no-loc text="Server":::** project's `Pages` folder. You can obtain the files from a project created from the Blazor Server template using Visual Studio or using the .NET CLI with the `dotnet new blazorserver -o BlazorServer` command in a command shell (the `-o BlazorServer` option creates a folder for the project). After placing the files into the **:::no-loc text="Server":::** project's `Pages` folder, make the following changes to the files.
-
- > [!IMPORTANT]
- > The use of a layout page (`_Layout.cshtml`) with a [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) for a component is required to control `` content, such as the page's title ( component) and other head elements ( component). For more information, see