From ad58a02759a6ec0d7eda17db91dad4e96bd55c62 Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Fri, 22 Aug 2025 10:15:29 -0400 Subject: [PATCH] Prerendering guidance organization --- aspnetcore/blazor/components/prerender.md | 64 +++++++++++++++++-- .../blazor/fundamentals/environments.md | 45 +------------ 2 files changed, 62 insertions(+), 47 deletions(-) diff --git a/aspnetcore/blazor/components/prerender.md b/aspnetcore/blazor/components/prerender.md index 22d215cbbd64..78dfb6628ca1 100644 --- a/aspnetcore/blazor/components/prerender.md +++ b/aspnetcore/blazor/components/prerender.md @@ -165,13 +165,70 @@ There are a four approaches that you can take to address this scenario for prere * 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. -* 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 . +* 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 the [Custom service implementation on the server](#custom-service-implementation-on-the-server) section. + +## Custom service implementation on the server + +In some cases, you can implement and inject a custom service on the server for an interface that's normally only implemented with a client-side service. For example, this approach works well for obtaining the environment during prerendering of an interactive WebAssembly or Auto component that resides in the `.Client` project of a Blazor Web App. + +Because the server doesn't have a registered service, it isn't possible to inject the service and use the service implementation's host environment extension methods and properties during server prerendering. Injecting the service into an interactive WebAssembly or Auto component results in the following runtime error: + +> :::no-loc text="There is no registered service of type 'Microsoft.AspNetCore.Components.WebAssembly.Hosting.IWebAssemblyHostEnvironment'."::: + +To address this, create a custom service implementation for on the server. Add the following class to the server project. + +`ServerHostEnvironment.cs`: + +```csharp +using Microsoft.AspNetCore.Components.WebAssembly.Hosting; +using Microsoft.AspNetCore.Components; + +public class ServerHostEnvironment(IWebHostEnvironment env, NavigationManager nav) : + IWebAssemblyHostEnvironment +{ + public string Environment => env.EnvironmentName; + public string BaseAddress => nav.BaseUri; +} +``` + +In the server project's `Program` file, register the service: + +```csharp +builder.Services.TryAddScoped(); +``` + +At this point, the service can be injected into an interactive WebAssembly or Auto component and used as shown in the [Read the environment in a Blazor WebAssembly app](xref:blazor/fundamentals/environments#read-the-environment-in-a-blazor-webassembly-app) section of the *Environments* article. + +The preceding example can demonstrate that it's possible to have a different server environment than client environment, which isn't recommended and may lead to arbitrary results. When setting the environment in a Blazor Web App, it's best to match server and `.Client` project environments. Consider the following scenario in a test app: + +* Implement the client-side (`webassembly`) environment property with the `Staging` environment via `Blazor.start`. See the [Set the client-side environment via startup configuration](xref:blazor/fundamentals/environments#set-the-client-side-environment-via-blazor-startup-configuration) section of the *Environments* article for an example. +* Don't change the server-side `Properties/launchSettings.json` file. Leave the `environmentVariables` section with the `ASPNETCORE_ENVIRONMENT` environment variable set to `Development`. + +You can see the value of the property change in the UI. + +When prerendering occurs on the server, the component is rendered in the `Development` environment: + +> **:::no-loc text="Environment:":::** :::no-loc text="Development"::: + +When the component is rerendered just a second or two later, after the Blazor bundle is downloaded and the .NET WebAssembly runtime activates, the value changes to reflect that the client is operating in the `Staging` environment on the client: + +> **:::no-loc text="Environment:":::** :::no-loc text="Staging"::: + +The preceding example demonstrates why we recommend setting the server environment to match the client environment for development, testing, and production deployments. :::moniker-end -## Prerendering guidance +## Prerendering guidance by feature + + + +Prerendering guidance is organized by feature. Use the following index to find specific guidance on prerendering. Alternatively, use a search engine with a filter to the Blazor documentation node. To obtain English-US results, search with `site:learn.microsoft.com/en-us/aspnet/core/ "prerendering"`. Change the locale segment (`en-us`) for a different language/region. -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: +[Google filtered search results for "prerendering" (English-US articles)](https://www.google.com/search?q=site:learn.microsoft.com/en-us/aspnet/core/+%22prerendering%22) * Fundamentals * [Overview: Client and server rendering concepts](xref:blazor/fundamentals/index#client-and-server-rendering-concepts) @@ -182,7 +239,6 @@ Prerendering guidance is organized in the Blazor documentation by subject matter * Startup * [Control headers in C# code](xref:blazor/fundamentals/startup#control-headers-in-c-code) * [Client-side loading indicators](xref:blazor/fundamentals/startup#client-side-loading-indicators) - * [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) * [Handle Errors: Prerendering](xref:blazor/fundamentals/handle-errors#prerendering) * SignalR * [Client-side rendering](xref:blazor/fundamentals/signalr#client-side-rendering) diff --git a/aspnetcore/blazor/fundamentals/environments.md b/aspnetcore/blazor/fundamentals/environments.md index ab5bf2ccd0e8..693253d17f52 100644 --- a/aspnetcore/blazor/fundamentals/environments.md +++ b/aspnetcore/blazor/fundamentals/environments.md @@ -114,7 +114,7 @@ Blazor Web App: **In the preceding example, the `{BLAZOR SCRIPT}` placeholder is the Blazor script path and file name.** For the location of the script, see . > [!NOTE] -> For Blazor Web Apps that set the `webAssembly` > `environment` property in `Blazor.start` configuration, it's wise to match the server-side environment to the environment set on the `environment` property. Otherwise, prerendering on the server will operate under a different environment than rendering on the client, which results in arbitrary effects. For general guidance on setting the environment for a Blazor Web App, see . +> For Blazor Web Apps that set the `webAssembly` > `environment` property in `Blazor.start` configuration, it's wise to match the server-side environment to the environment set on the `environment` property. Otherwise, prerendering on the server operates under a different environment than rendering on the client, which results in arbitrary effects. For general guidance on setting the environment for a Blazor Web App, see . Standalone Blazor WebAssembly: @@ -269,48 +269,7 @@ Assuming that prerendering isn't disabled for a component or the app, a componen > :::no-loc text="There is no registered service of type 'Microsoft.AspNetCore.Components.WebAssembly.Hosting.IWebAssemblyHostEnvironment'."::: -To address this, create a custom service implementation for on the server. Add the following class to the server project. - -`ServerHostEnvironment.cs`: - -```csharp -using Microsoft.AspNetCore.Components.WebAssembly.Hosting; -using Microsoft.AspNetCore.Components; - -public class ServerHostEnvironment(IWebHostEnvironment env, NavigationManager nav) : - IWebAssemblyHostEnvironment -{ - public string Environment => env.EnvironmentName; - public string BaseAddress => nav.BaseUri; -} -``` - -In the server project's `Program` file, register the service: - -```csharp -builder.Services.TryAddScoped(); -``` - -At this point, the service can be injected into an interactive WebAssembly or interactive Auto component and used as shown in the [Read the environment in a Blazor WebAssembly app](#read-the-environment-in-a-blazor-webassembly-app) section. - -The preceding example can demonstrate that it's possible to have a different server environment than client environment, which isn't recommended and may lead to arbitrary results. When setting the environment in a Blazor Web App, it's best to match server and `.Client` project environments. Consider the following scenario in a test app: - -* Implement the client-side (`webassembly`) environment property with the `Staging` environment via `Blazor.start`. See the [Set the client-side environment via startup configuration](#set-the-client-side-environment-via-blazor-startup-configuration) section for an example. -* Don't change the server-side `Properties/launchSettings.json` file. Leave the `environmentVariables` section with the `ASPNETCORE_ENVIRONMENT` environment variable set to `Development`. - -You can see the value of the property change in the UI. - -When prerendering occurs on the server, the component is rendered in the `Development` environment: - -> **:::no-loc text="Environment:":::** :::no-loc text="Development"::: - -When the component is rerendered just a second or two later, after the Blazor bundle is downloaded and the .NET WebAssembly runtime activates, the values change to reflect that the client is operating in the `Staging` environment on the client: - -> **:::no-loc text="Environment:":::** :::no-loc text="Staging"::: - -The preceding example demonstrates why we recommend setting the server environment to match the client environment for development, testing, and production deployments. - -For more information, see the [Client-side services fail to resolve during prerendering](xref:blazor/components/prerender#client-side-services-fail-to-resolve-during-prerendering) section of the *Prerendering* article, which appears later in the Blazor documentation. +To address this, create a custom service implementation for on the server. For more information and an example implementation, see the [Custom service implementation on the server](xref:blazor/components/prerender#custom-service-implementation-on-the-server) section of the *Prerendering* article, which appears later in the Blazor documentation. :::moniker-end