You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: aspnetcore/blazor/components/prerender.md
+65-78Lines changed: 65 additions & 78 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -25,7 +25,7 @@ This article explains Razor component prerendering scenarios for server-rendered
25
25
26
26
Prerendering is enabled by default for interactive components.
27
27
28
-
Internal navigation for interactive routing doesn't involve requesting new page content from the server. Therefore, prerendering doesn't occur for internal page requests, including for [enhanced navigation](xref:blazor/fundamentals/routing#enhanced-navigation-and-form-handling). For more information, see [Static versus interactive routing](xref:blazor/fundamentals/routing#static-versus-interactive-routing), [Interactive routing and prerendering](xref:blazor/state-management/prerendered-state-persistence#interactive-routing-and-prerendering), and [Enhanced navigation and form handling](xref:blazor/fundamentals/routing#enhanced-navigation-and-form-handling).
28
+
Internal navigation with interactive routing doesn't use prerendering because the page is already interactive. For more information, see [Static versus interactive routing](xref:blazor/fundamentals/routing#static-versus-interactive-routing) and [Interactive routing and prerendering](xref:blazor/state-management/prerendered-state-persistence#interactive-routing-and-prerendering).
29
29
30
30
[`OnAfterRender{Async}` component lifecycle events](xref:blazor/components/lifecycle#after-component-render-onafterrenderasync) aren't called when prerendering, only after the component renders interactively.
31
31
@@ -103,7 +103,53 @@ No compile time error occurs, but a runtime error occurs during prerendering:
103
103
104
104
This error occurs because the component must compile and execute on the server during prerendering, but <xref:Microsoft.AspNetCore.Components.WebAssembly.Hosting.IWebAssemblyHostEnvironment> isn't a registered service on the server.
105
105
106
-
If the app doesn't require the value during prerendering, this problem can be solved by injecting <xref:System.IServiceProvider> to obtain the service instead of the service type itself:
106
+
Consider any of the following approaches to address this scenario:
107
+
108
+
*[Register the service on the server in addition to the client](#register-the-service-on-the-server-in-addition-to-the-client)
109
+
*[Inject a service that the app can use during prerendering](#inject-a-service-that-the-app-can-use-during-prerendering)
110
+
*[Make the service optional](#make-the-service-optional)
111
+
*[Create a service abstraction](#create-a-service-abstraction)
112
+
*[Disable prerendering for the component](#disable-prerendering-for-the-component)
113
+
114
+
### Register the service on the server in addition to the client
115
+
116
+
If the service supports server execution, register the service on the server in addition to the client so that it's available during prerendering. For an example of this scenario, see the guidance for <xref:System.Net.Http.HttpClient> services in the [Blazor Web App external web APIs](xref:blazor/call-web-api#blazor-web-app-external-web-apis) section of the *Call web API* article.
117
+
118
+
### Inject a service that the app can use during prerendering
119
+
120
+
In some cases, the app can use a service on the server during prerendering and a different service on the client.
121
+
122
+
For example, the following code obtains the app's environment whether the code is running on the server or on the client by injecting <xref:Microsoft.Extensions.Hosting.IHostEnvironment> from the [`Microsoft.Extensions.Hosting.Abstractions` NuGet package](https://www.nuget.org/packages/Microsoft.Extensions.Hosting.Abstractions):
However, this approach adds an additional dependency to the client project that isn't needed.
136
+
137
+
### Make the service optional
138
+
139
+
Make the service optional if it isn't required during prerendering using either of the following approaches.
140
+
141
+
The following example uses constructor injection of <xref:Microsoft.AspNetCore.Components.WebAssembly.Hosting.IWebAssemblyHostEnvironment>:
142
+
143
+
```csharp
144
+
privatestring?environmentName;
145
+
146
+
publicHome(IWebAssemblyHostEnvironment?env=null)
147
+
{
148
+
environmentName=env?.Environment;
149
+
}
150
+
```
151
+
152
+
Alternatively, inject <xref:System.IServiceProvider> to optionally obtain the service if it's available:
107
153
108
154
```razor
109
155
@page "/"
@@ -131,95 +177,36 @@ If the app doesn't require the value during prerendering, this problem can be so
131
177
}
132
178
```
133
179
134
-
If you merely want to make the service injection optional, you can use constructor injection:
180
+
### Create a service abstraction
135
181
136
-
```csharp
137
-
privatestring?environmentName;
182
+
If a different service implementation is needed on the server, create a service abstraction and create implementations for the service in the server and client projects. Register the services in each project. Inject the custom service abstraction into components where needed. The component then depends solely on the custom service abstraction.
138
183
139
-
publicHome(IWebAssemblyHostEnvironment?env=null)
140
-
{
141
-
environmentName=env?.Environment;
142
-
}
143
-
```
184
+
In the case of <xref:Microsoft.AspNetCore.Components.WebAssembly.Hosting.IWebAssemblyHostEnvironment>, we can reuse the existing interface instead of creating a new one:
144
185
145
-
Another option for obtaining the environment whether the code is running on the server or on the client is to inject <xref:Microsoft.Extensions.Hosting.IHostEnvironment> from the [`Microsoft.Extensions.Hosting.Abstractions` NuGet package](https://www.nuget.org/packages/Microsoft.Extensions.Hosting.Abstractions). Add a package reference to the app and use the following approach:
You can also avoid the problem if you [disable prerendering](#disable-prerendering) for the component, but that's an extreme measure to take in many cases that may not meet your component's specifications.
159
-
160
-
There are a four approaches that you can take to address this scenario for prerendering. The following are listed from most recommended to least recommended:
200
+
In the server project's `Program` file, register the service:
161
201
162
-
* For shared framework services that merely aren't registered server-side in the main project, register the services in the main project, which makes them available during prerendering. For an example of this scenario, see the guidance for <xref:System.Net.Http.HttpClient> services in the [Blazor Web App external web APIs](xref:blazor/call-web-api#blazor-web-app-external-web-apis) section of the *Call web API* article.
* Make the service optional if it isn't always needed. See the first two examples in this section.
206
+
At this point, the <xref:Microsoft.AspNetCore.Components.WebAssembly.Hosting.IWebAssemblyHostEnvironment>service can be [injected into an interactive WebAssembly or Auto component that is also prerendered from the server](xref:blazor/fundamentals/environments#read-the-environment-in-a-blazor-webassembly-app).
165
207
166
-
* Create a service abstraction and create implementations for the service in the `.Client` and server projects. Register the services in each project. Inject the custom service abstraction in the component.
208
+
### Disable prerendering for the component
167
209
168
-
* For services outside of the shared framework, create a custom service implementation for the service on the server. Use the service normally in interactive components of the `.Client` project. For a demonstration of this approach, see <xref:blazor/fundamentals/environments#read-the-environment-client-side-in-a-blazor-web-app>.
210
+
Disable prerendering for the component or for the entire app. For more information, see the [Disable prerendering](#disable-prerendering) section.
169
211
170
212
:::moniker-end
171
-
172
-
## Prerendering guidance
173
-
174
-
Prerendering guidance is organized in the Blazor documentation by subject matter. The following links cover all of the prerendering guidance throughout the documentation set by subject:
175
-
176
-
* Fundamentals
177
-
*[Overview: Client and server rendering concepts](xref:blazor/fundamentals/index#client-and-server-rendering-concepts)
178
-
* Routing
179
-
*[Static versus interactive routing](xref:blazor/fundamentals/routing#static-versus-interactive-routing)
180
-
*[Route to components from multiple assemblies: Interactive routing](xref:blazor/fundamentals/routing#interactive-routing)
181
-
*<xref:Microsoft.AspNetCore.Components.Routing.Router.OnNavigateAsync> is executed *twice* when prerendering: [Handle asynchronous navigation events with `OnNavigateAsync`](xref:blazor/fundamentals/routing#handle-asynchronous-navigation-events-with-onnavigateasync)
182
-
* Startup
183
-
*[Control headers in C# code](xref:blazor/fundamentals/startup#control-headers-in-c-code)
*[Environments: Read the environment client-side in a Blazor Web App](xref:blazor/fundamentals/environments#read-the-environment-client-side-in-a-blazor-web-app)
*[Prerendered state size and SignalR message size limit](xref:blazor/fundamentals/signalr#prerendered-state-size-and-signalr-message-size-limit)
190
-
191
-
* Components
192
-
*[Control `<head>` content during prerendering](xref:blazor/components/control-head-content#control-head-content-during-prerendering)
193
-
* Render modes
194
-
*[Detect rendering location, interactivity, and assigned render mode at runtime](xref:blazor/components/render-modes#detect-rendering-location-interactivity-and-assigned-render-mode-at-runtime)
*[Stateful reconnection after prerendering](xref:blazor/components/lifecycle#stateful-reconnection-after-prerendering)
200
-
*[Prerendering with JavaScript interop](xref:blazor/components/lifecycle#prerendering-with-javascript-interop): This section also appears in the two JS interop articles on calling JavaScript from .NET and calling .NET from JavaScript.
201
-
*[Handle incomplete asynchronous actions at render](xref:blazor/components/lifecycle#handle-incomplete-asynchronous-actions-at-render): Guidance for delayed rendering due to long-running lifecycle tasks during prerendering on the server.
202
-
*[`QuickGrid` component sample app](xref:blazor/components/quickgrid#sample-app): The [**QuickGrid for Blazor** sample app](https://aspnet.github.io/quickgridsamples/) is hosted on GitHub Pages. The site loads fast thanks to static prerendering using the community-maintained [`BlazorWasmPrerendering.Build` GitHub project](https://github.com/jsakamoto/BlazorWasmPreRendering.Build).
203
-
*[Prerendering when integrating components into Razor Pages and MVC apps](xref:blazor/components/integration)
204
-
205
-
*[Call a web API: Prerendered data](xref:blazor/call-web-api#prerendered-data)
206
-
207
-
*[File uploads: Upload files to a server with client-side rendering (CSR)](xref:blazor/file-uploads#upload-files-to-a-server-with-client-side-rendering-csr)
208
-
209
-
*[Globalization and localization: Location override using "Sensors" pane in developer tools](xref:blazor/globalization-localization#location-override-using-sensors-pane-in-developer-tools)
*[Manage authentication state in Blazor Web Apps](xref:blazor/security/index#manage-authentication-state-in-blazor-web-apps)
215
-
*[Unauthorized content display while prerendering with a custom `AuthenticationStateProvider`](xref:blazor/security/index#unauthorized-content-display-while-prerendering-with-a-custom-authenticationstateprovider)
216
-
*[Blazor server-side additional scenarios: Reading tokens from `HttpContext`](xref:blazor/security/additional-scenarios#reading-tokens-from-httpcontext)
*[State management: Protected browser storage: Handle prerendering](xref:blazor/state-management/protected-browser-storage#handle-prerendering): Besides the *Handle prerendering* section, several article sections in the [State management node](xref:blazor/state-management/index) include remarks on prerendering.
224
-
225
-
For .NET 7 or earlier, see [Blazor WebAssembly security additional scenarios: Prerendering with authentication](xref:blazor/security/webassembly/additional-scenarios?view=aspnetcore-7.0&preserve-view=true#prerendering-with-authentication). After viewing the content in this section, reset the documentation article version selector dropdown to the latest .NET release version to ensure that documentation pages load for the latest release on subsequent visits.
0 commit comments