Prerender and integrate ASP.NET Core Razor components
Razor components can be integrated into Razor Pages and MVC apps in a hosted Blazor WebAssembly solution. When the page or view is rendered, components can be prerendered at the same time.
Configuration
To set up prerendering for a Blazor WebAssembly app:
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 Hosted project template.
Remove the default static
wwwroot/index.html
file from the Blazor WebAssembly client project.Delete the following line in
Program.Main
in the client project:builder.RootComponents.Add<App>("#app");
Add a
Pages/_Host.cshtml
file to the server project. You can obtain a_Host.cshtml
file from an app created from the Blazor Server template with thedotnet new blazorserver -o BlazorServer
command in a command shell. After placing thePages/_Host.cshtml
file into the server app of the hosted Blazor WebAssembly solution, make the following changes to the file:Set the namespace to the server app's
Pages
folder (for example,@namespace BlazorHosted.Server.Pages
).Set an
@using
directive for the client project (for example,@using BlazorHosted.Client
).Update the stylesheet links to point to the WebAssembly app's stylesheet. In the following example, the client app's namespace is
BlazorHosted.Client
:<link href="css/app.css" rel="stylesheet" /> <link href="BlazorHosted.Client.styles.css" rel="stylesheet" />
Update the
render-mode
of the Component Tag Helper to prerender the rootApp
component:<component type="typeof(App)" render-mode="WebAssemblyPrerendered" />
Update the Blazor script source to use the client-side Blazor WebAssembly script:
<script src="_framework/blazor.webassembly.js"></script>
In
Startup.Configure
(Startup.cs
) of the server project:- Call
UseDeveloperExceptionPage
on the app builder in the Development environment. - Call
UseBlazorFrameworkFiles
on the app builder. - Change the fallback from the
index.html
page (endpoints.MapFallbackToFile("index.html");
) to the_Host.cshtml
page.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseWebAssemblyDebugging(); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseBlazorFrameworkFiles(); app.UseStaticFiles(); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); endpoints.MapControllers(); endpoints.MapFallbackToPage("/_Host"); }); }
- Call
Render components in a page or view with the Component Tag Helper
The Component Tag Helper supports two render modes for rendering a component from a Blazor WebAssembly app in a page or view:
WebAssembly
: Renders a marker for a Blazor WebAssembly app for use to include an interactive component when loaded in the browser. The component isn't prerendered. This option makes it easier to render different Blazor WebAssembly components on different pages.WebAssemblyPrerendered
: Prerenders the component into static HTML and includes a marker for a Blazor WebAssembly app for later use to make the component interactive when loaded in the browser.
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. To avoid using the full namespace for the Counter
component with the Component Tag Helper ({APP ASSEMBLY}.Pages.Counter
), add an @using
directive for the client app's Pages
namespace. In the following example, the client app's namespace is BlazorHosted.Client
:
...
@using BlazorHosted.Client.Pages
<h1>@ViewData["Title"]</h1>
<component type="typeof(Counter)" render-mode="WebAssemblyPrerendered" />
@section Scripts {
<script src="_framework/blazor.webassembly.js"></script>
}
RenderMode 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 RenderMode configuration, see Component Tag Helper in ASP.NET Core.
The preceding example requires that the server app's layout (_Layout.cshtml
) include a render section (RenderSection) for the script inside the closing </body>
tag:
...
@RenderSection("Scripts", required: false)
</body>
The _Layout.cshtml
file is located in the Pages/Shared
folder in a Razor Pages app or Views/Shared
folder in an MVC app.
If the app should also style components with the styles in the Blazor WebAssembly app, include the app's styles in the _Layout.cshtml
file. In the following example, the client app's namespace is BlazorHosted.Client
:
<head>
...
<link href="css/app.css" rel="stylesheet" />
<link href="BlazorHosted.Client.styles.css" rel="stylesheet" />
</head>
Render components in a page or view with a CSS selector
Add root components to the Client project in Program.Main
(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 my-counter
. In the following example, the client app's namespace is BlazorHosted.Client
:
using BlazorHosted.Client.Pages;
...
builder.RootComponents.Add<Counter>("#my-counter");
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:
...
<h1>@ViewData["Title"]</h1>
<div id="my-counter">Loading...</div>
@section Scripts {
<script src="_framework/blazor.webassembly.js"></script>
}
The preceding example requires that the server app's layout (_Layout.cshtml
) include a render section (RenderSection) for the script inside the closing </body>
tag:
...
@RenderSection("Scripts", required: false)
</body>
The _Layout.cshtml
file is located in the Pages/Shared
folder in a Razor Pages app or Views/Shared
folder in an MVC app.
If the app should also style components with the styles in the Blazor WebAssembly app, include the app's styles in the _Layout.cshtml
file. In the following example, the client app's namespace is BlazorHosted.Client
:
<head>
...
<link href="css/app.css" rel="stylesheet" />
<link href="BlazorHosted.Client.styles.css" rel="stylesheet" />
</head>
Integrating Razor components into Razor Pages and MVC apps in a hosted Blazor WebAssembly solution is supported in ASP.NET Core in .NET 5 or later. Select a .NET 5 or later version of this article.
Razor components can be integrated into Razor Pages and MVC apps in a Blazor Server app. When the page or view is rendered, components can be prerendered at the same time.
After configuring the app, use the guidance in the following sections depending on the app'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
directive. - 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.
Configuration
An existing Razor Pages or MVC app can integrate Razor components into pages and views:
In the app's layout file (
_Layout.cshtml
):Add the following
<base>
tag to the<head>
element:<base href="~/" />
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 Host and deploy ASP.NET Core Blazor article.The
_Layout.cshtml
file is located in thePages/Shared
folder in a Razor Pages app orViews/Shared
folder in an MVC app.Add a
<script>
tag for theblazor.server.js
script immediately before theScripts
render section:... <script src="_framework/blazor.server.js"></script> @await RenderSectionAsync("Scripts", required: false) </body>
The framework adds the
blazor.server.js
script to the app. There's no need to manually add the script to the app.
Add an
_Imports.razor
file to the root folder of the project with the following content (change the last namespace,MyAppNamespace
, to the namespace of the app):@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 MyAppNamespace
In
Startup.ConfigureServices
, register the Blazor Server service:services.AddServerSideBlazor();
In
Startup.Configure
, add the Blazor Hub endpoint toapp.UseEndpoints
:endpoints.MapBlazorHub();
Integrate components into any page or view. For more information, see the 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:
Follow the guidance in the Configuration section.
Add an
App.razor
file to the project root with the following content:@using Microsoft.AspNetCore.Components.Routing <Router AppAssembly="@typeof(Program).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData" /> </Found> <NotFound> <h1>Page not found</h1> <p>Sorry, but there's nothing here!</p> </NotFound> </Router>
Note
With the release of ASP.NET Core 5.0.1 and for any additional 5.x releases, the
Router
component includes thePreferExactMatches
parameter set to@true
. For more information, see Migrate from ASP.NET Core 3.1 to 5.0.Add a
_Host.cshtml
file to thePages
folder with the following content:@page "/blazor" @{ Layout = "_Layout"; } <app> <component type="typeof(App)" render-mode="ServerPrerendered" /> </app>
Components use the shared
_Layout.cshtml
file for their layout.RenderMode 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 RenderMode configuration, see Component Tag Helper in ASP.NET Core.
Add a low-priority route for the
_Host.cshtml
page to endpoint configuration inStartup.Configure
:app.UseEndpoints(endpoints => { ... endpoints.MapFallbackToPage("/_Host"); });
Add routable components to the app. For example:
@page "/counter" <h1>Counter</h1> ...
For more information on namespaces, see the 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:
Follow the guidance in the Configuration section.
Add an
App.razor
file to the root of the project with the following content:@using Microsoft.AspNetCore.Components.Routing <Router AppAssembly="@typeof(Program).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData" /> </Found> <NotFound> <h1>Page not found</h1> <p>Sorry, but there's nothing here!</p> </NotFound> </Router>
Note
With the release of ASP.NET Core 5.0.1 and for any additional 5.x releases, the
Router
component includes thePreferExactMatches
parameter set to@true
. For more information, see Migrate from ASP.NET Core 3.1 to 5.0.Add a
_Host.cshtml
file to theViews/Home
folder with the following content:@{ Layout = "_Layout"; } <app> <component type="typeof(App)" render-mode="ServerPrerendered" /> </app>
Components use the shared
_Layout.cshtml
file for their layout.RenderMode 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 RenderMode configuration, see Component Tag Helper in ASP.NET Core.
Add an action to the Home controller:
public IActionResult Blazor() { return View("_Host"); }
Add a low-priority route for the controller action that returns the
_Host.cshtml
view to the endpoint configuration inStartup.Configure
:app.UseEndpoints(endpoints => { ... endpoints.MapFallbackToController("Blazor", "Home"); });
Create a
Pages
folder and add routable components to the app. For example:@page "/counter" <h1>Counter</h1> ...
For more information on namespaces, see the 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.
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:
<h1>My Razor Page</h1>
<component type="typeof(Counter)" render-mode="ServerPrerendered"
param-InitialValue="InitialValue" />
@functions {
[BindProperty(SupportsGet=true)]
public int InitialValue { get; set; }
}
For more information, see Component Tag Helper in ASP.NET Core.
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:
<h1>My Razor Page</h1>
<form>
<input type="number" asp-for="InitialValue" />
<button type="submit">Set initial value</button>
</form>
<component type="typeof(Counter)" render-mode="Static"
param-InitialValue="InitialValue" />
@functions {
[BindProperty(SupportsGet=true)]
public int InitialValue { get; set; }
}
For more information, see Component Tag Helper in ASP.NET Core.
Component namespaces
When using a custom folder to hold the app's components, add the namespace representing the folder to either the page/view or to the _ViewImports.cshtml
file. In the following example:
- Change
MyAppNamespace
to the app's namespace. - If a folder named
Components
isn't used to hold the components, changeComponents
to the folder where the components reside.
@using MyAppNamespace.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 Create and use ASP.NET Core Razor components.