Movatterモバイル変換


[0]ホーム

URL:


Skip to main content

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Download Microsoft EdgeMore info about Internet Explorer and Microsoft Edge
Table of contentsExit editor mode

ASP.NET Core Blazor startup

Feedback

In this article

Note

This isn't the latest version of this article. For the current release, see the.NET 10 version of this article.

Warning

This version of ASP.NET Core is no longer supported. For more information, see the.NET and .NET Core Support Policy. For the current release, see the.NET 9 version of this article.

This article explains Blazor app startup configuration.

For general guidance on ASP.NET Core app configuration for server-side development, seeConfiguration in ASP.NET Core.

Startup process and configuration

The Blazor startup process is automatic and asynchronous via the Blazor script (blazor.*.js), where the* placeholder is:

  • web for a Blazor Web App
  • server for a Blazor Server app
  • webassembly for a Blazor WebAssembly app

The Blazor startup process is automatic and asynchronous via the Blazor script (blazor.*.js), where the* placeholder is:

  • server for a Blazor Server app
  • webassembly for a Blazor WebAssembly app

For the location of the script, seeASP.NET Core Blazor project structure.

To manually start Blazor:

Blazor Web App:

  • Add anautostart="false" attribute and value to the Blazor<script> tag.
  • Place a script that callsBlazor.start() after the Blazor<script> tag and inside the closing</body> tag.
  • Place static server-side rendering (static SSR) options in thessr property.
  • Place server-side Blazor-SignalR circuit options in thecircuit property.
  • Place client-side WebAssembly options in thewebAssembly property.
<script src="{BLAZOR SCRIPT}" autostart="false"></script><script>  ...  Blazor.start({    ssr: {      ...    },    circuit: {      ...    },    webAssembly: {      ...    }  });  ...</script>

Standalone Blazor WebAssembly and Blazor Server:

  • Add anautostart="false" attribute and value to the Blazor<script> tag.
  • Place a script that callsBlazor.start() after the Blazor<script> tag and inside the closing</body> tag.
  • You can provide additional options in theBlazor.start() parameter.
<script src="{BLAZOR SCRIPT}" autostart="false"></script><script>  ...  Blazor.start({    ...  });  ...</script>

In the preceding example, the{BLAZOR SCRIPT} placeholder is the Blazor script path and file name. For the location of the script, seeASP.NET Core Blazor project structure.

JavaScript initializers

JavaScript (JS) initializers execute logic before and after a Blazor app loads. JS initializers are useful in the following scenarios:

  • Customizing how a Blazor app loads.
  • Initializing libraries before Blazor starts up.
  • Configuring Blazor settings.

JS initializers are detected as part of the build process and imported automatically. Use of JS initializers often removes the need tomanually trigger script functions from the app when usingRazor class libraries (RCLs).

To define a JS initializer, add a JS module to the project named{NAME}.lib.module.js, where the{NAME} placeholder is the assembly name, library name, or package identifier. Place the file in the project's web root, which is typically thewwwroot folder.

For Blazor Web Apps:

  • beforeWebStart(options): Called before the Blazor Web App starts. For example,beforeWebStart is used to customize the loading process, logging level, and other options. Receives the Blazor Web options (options).
  • afterWebStarted(blazor): Called after allbeforeWebStart promises resolve. For example,afterWebStarted can be used to register Blazor event listeners and custom event types. The Blazor instance is passed toafterWebStarted as an argument (blazor).
  • beforeServerStart(options, extensions): Called before the first Server runtime is started. Receives SignalR circuit start options (options) and any extensions (extensions) added during publishing.
  • afterServerStarted(blazor): Called after the first Interactive Server runtime is started.
  • beforeWebAssemblyStart(options, extensions): Called before the Interactive WebAssembly runtime is started. Receives the Blazor options (options) and any extensions (extensions) added during publishing. For example, options can specify the use of a customboot resource loader.
  • afterWebAssemblyStarted(blazor): Called after the Interactive WebAssembly runtime is started.

Note

Legacy JS initializers (beforeStart,afterStarted) aren't invoked by default in a Blazor Web App. You can enable the legacy initializers to run with theenableClassicInitializers option. However, legacy initializer execution is unpredictable.

<script>  Blazor.start({ enableClassicInitializers: true });</script>

Due to aframework bug in .NET 8 and 9 (dotnet/aspnetcore #54049), the Blazor script must be manually started whenbeforeWebAssemblyStart(options, extensions) orafterWebAssemblyStarted(blazor) are called. If the server app doesn't already start Blazor manually with a WebAssembly (webAssembly: {...}) configuration, update theApp component in the server project with the following.

InComponents/App.razor, remove the existing Blazor<script> tag:

- <script src="_framework/blazor.web.js"></script>

Replace the<script> tag with the following markup that starts Blazor manually with a WebAssembly (webAssembly: {...}) configuration:

<script src="_framework/blazor.web.js" autostart="false"></script><script>    Blazor.start({        webAssembly: {}    });</script>

For Blazor Server, Blazor WebAssembly, and Blazor Hybrid apps:

  • beforeStart(options, extensions): Called before Blazor starts. For example,beforeStart is used to customize the loading process, logging level, and other options specific to the hosting model.
    • Client-side,beforeStart receives the Blazor options (options) and any extensions (extensions) added during publishing. For example, options can specify the use of a customboot resource loader.
    • Server-side,beforeStart receives SignalR circuit start options (options).
    • In aBlazorWebView, no options are passed.
  • afterStarted(blazor): Called after Blazor is ready to receive calls from JS. For example,afterStarted is used to initialize libraries by making JS interop calls and registering custom elements. The Blazor instance is passed toafterStarted as an argument (blazor).

Additional .NET WebAssembly runtime callbacks:

  • onRuntimeConfigLoaded(config): Called when the boot configuration is downloaded. Allows the app to modify parameters (config) before the runtime starts (the parameter isMonoConfig fromdotnet.d.ts):

    export function onRuntimeConfigLoaded(config) {  // Sample: Enable startup diagnostic logging when the URL contains   // parameter debug=1  const params = new URLSearchParams(location.search);  if (params.get("debug") == "1") {    config.diagnosticTracing = true;  }}
  • onRuntimeReady({ getAssemblyExports, getConfig }): Called after the .NET WebAssembly runtime has started (the parameter isRuntimeAPI fromdotnet.d.ts):

    export function onRuntimeReady({ getAssemblyExports, getConfig }) {  // Sample: After the runtime starts, but before Main method is called,   // call [JSExport]ed method.  const config = getConfig();  const exports = await getAssemblyExports(config.mainAssemblyName);  exports.Sample.Greet();}

Both callbacks can return aPromise, and the promise is awaited before the startup continues.

For the file name:

  • If the JS initializers are consumed as a static asset in the project, use the format{ASSEMBLY NAME}.lib.module.js, where the{ASSEMBLY NAME} placeholder is the app's assembly name. For example, name the fileBlazorSample.lib.module.js for a project with an assembly name ofBlazorSample. Place the file in the app'swwwroot folder.
  • If the JS initializers are consumed from an RCL, use the format{LIBRARY NAME/PACKAGE ID}.lib.module.js, where the{LIBRARY NAME/PACKAGE ID} placeholder is the project's library name or package identifier (<PackageId> value in the library's project file). For example, name the fileRazorClassLibrary1.lib.module.js for an RCL with a package identifier ofRazorClassLibrary1. Place the file in the library'swwwroot folder.

For Blazor Web Apps:

The following example demonstrates JS initializers that load custom scripts before and after the Blazor Web App has started by appending them to the<head> inbeforeWebStart andafterWebStarted:

export function beforeWebStart() {  var customScript = document.createElement('script');  customScript.setAttribute('src', 'beforeStartScripts.js');  document.head.appendChild(customScript);}export function afterWebStarted() {  var customScript = document.createElement('script');  customScript.setAttribute('src', 'afterStartedScripts.js');  document.head.appendChild(customScript);}

The precedingbeforeWebStart example only guarantees that the custom script loads before Blazor starts. It doesn't guarantee that awaited promises in the script complete their execution before Blazor starts.

For Blazor Server, Blazor WebAssembly, and Blazor Hybrid apps:

The following example demonstrates JS initializers that load custom scripts before and after Blazor has started by appending them to the<head> inbeforeStart andafterStarted:

export function beforeStart(options, extensions) {  var customScript = document.createElement('script');  customScript.setAttribute('src', 'beforeStartScripts.js');  document.head.appendChild(customScript);}export function afterStarted(blazor) {  var customScript = document.createElement('script');  customScript.setAttribute('src', 'afterStartedScripts.js');  document.head.appendChild(customScript);}

The precedingbeforeStart example only guarantees that the custom script loads before Blazor starts. It doesn't guarantee that awaited promises in the script complete their execution before Blazor starts.

Note

MVC and Razor Pages apps don't automatically load JS initializers. However, developer code can include a script to fetch the app's manifest and trigger the load of the JS initializers.

For examples of JS initializers, see the following resources:

Note

Documentation links to .NET reference source usually load the repository's default branch, which represents the current development for the next release of .NET. To select a tag for a specific release, use theSwitch branches or tags dropdown list. For more information, seeHow to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205).

Ensure libraries are loaded in a specific order

Append custom scripts to the<head> inbeforeStart andafterStarted in the order that they should load.

The following example loadsscript1.js beforescript2.js andscript3.js beforescript4.js:

export function beforeStart(options, extensions) {    var customScript1 = document.createElement('script');    customScript1.setAttribute('src', 'script1.js');    document.head.appendChild(customScript1);    var customScript2 = document.createElement('script');    customScript2.setAttribute('src', 'script2.js');    document.head.appendChild(customScript2);}export function afterStarted(blazor) {    var customScript1 = document.createElement('script');    customScript1.setAttribute('src', 'script3.js');    document.head.appendChild(customScript1);    var customScript2 = document.createElement('script');    customScript2.setAttribute('src', 'script4.js');    document.head.appendChild(customScript2);}

Import additional modules

Use top-levelimport statements in the JS initializers file to import additional modules.

additionalModule.js:

export function logMessage() {  console.log('logMessage is logging');}

In the JS initializers file (.lib.module.js):

import { logMessage } from "/additionalModule.js";export function beforeStart(options, extensions) {  ...  logMessage();}

Import map

Import maps are supported by ASP.NET Core and Blazor.

Initialize Blazor when the document is ready

The following example starts Blazor when the document is ready:

<script src="{BLAZOR SCRIPT}" autostart="false"></script><script>  document.addEventListener("DOMContentLoaded", function() {    Blazor.start();  });</script>

In the preceding example, the{BLAZOR SCRIPT} placeholder is the Blazor script path and file name. For the location of the script, seeASP.NET Core Blazor project structure.

Chain to thePromise that results from a manual start

To perform additional tasks, such as JS interop initialization, usethen to chain to thePromise that results from a manual Blazor app start:

<script src="{BLAZOR SCRIPT}" autostart="false"></script><script>  Blazor.start().then(function () {    ...  });</script>

In the preceding example, the{BLAZOR SCRIPT} placeholder is the Blazor script path and file name. For the location of the script, seeASP.NET Core Blazor project structure.

Note

For a library to automatically execute additional tasks after Blazor has started, use aJavaScript initializer. Use of a JS initializer doesn't require the consumer of the library to chain JS calls to Blazor's manual start.

Load client-side boot resources

When an app loads in the browser, the app downloads boot resources from the server:

  • JavaScript code to bootstrap the app
  • .NET runtime and assemblies
  • Locale specific data

Customize how these boot resources are loaded using theloadBootResource API. TheloadBootResource function overrides the built-in boot resource loading mechanism. UseloadBootResource for the following scenarios:

  • Load static resources, such as timezone data ordotnet.wasm, from a CDN.
  • Load compressed assemblies using an HTTP request and decompress them on the client for hosts that don't support fetching compressed contents from the server.
  • Alias resources to a different name by redirecting eachfetch request to a new name.

Note

External sources must return the requiredCross-Origin Resource Sharing (CORS) headers for browsers to allow cross-origin resource loading. CDNs usually provide the required headers.

loadBootResource parameters appear in the following table.

ParameterDescription
typeThe type of the resource. Permissible types include:assembly,pdb,dotnetjs,dotnetwasm, andtimezonedata. You only need to specify types for custom behaviors. Types not specified toloadBootResource are loaded by the framework per their default loading behaviors. Thedotnetjs boot resource (dotnet.*.js) must either returnnull for default loading behavior or a URI for the source of thedotnetjs boot resource.
nameThe name of the resource.
defaultUriThe relative or absolute URI of the resource.
integrityThe integrity string representing the expected content in the response.

TheloadBootResource function can return a URI string to override the loading process. In the following example, the following files frombin/Release/{TARGET FRAMEWORK}/wwwroot/_framework are served from a CDN athttps://cdn.example.com/blazorwebassembly/{VERSION}/:

  • dotnet.*.js
  • dotnet.wasm
  • Timezone data

The{TARGET FRAMEWORK} placeholder is the target framework moniker (for example,net7.0). The{VERSION} placeholder is the shared framework version (for example,7.0.0).

Blazor Web App:

<script src="{BLAZOR SCRIPT}" autostart="false"></script><script>  Blazor.start({    webAssembly: {      loadBootResource: function (type, name, defaultUri, integrity) {        console.log(`Loading: '${type}', '${name}', '${defaultUri}', '${integrity}'`);        switch (type) {          case 'dotnetjs':          case 'dotnetwasm':          case 'timezonedata':            return `https://cdn.example.com/blazorwebassembly/{VERSION}/${name}`;        }      }    }  });</script>

Standalone Blazor WebAssembly:

<script src="{BLAZOR SCRIPT}" autostart="false"></script><script>  Blazor.start({    loadBootResource: function (type, name, defaultUri, integrity) {      console.log(`Loading: '${type}', '${name}', '${defaultUri}', '${integrity}'`);      switch (type) {        case 'dotnetjs':        case 'dotnetwasm':        case 'timezonedata':          return `https://cdn.example.com/blazorwebassembly/{VERSION}/${name}`;      }    }  });</script>

In the preceding example, the{BLAZOR SCRIPT} placeholder is the Blazor script path and file name. For the location of the script, seeASP.NET Core Blazor project structure.

To customize more than just the URLs for boot resources, theloadBootResource function can callfetch directly and return the result. The following example adds a custom HTTP header to the outbound requests. To retain the default integrity checking behavior, pass through theintegrity parameter.

Blazor Web App:

<script src="{BLAZOR SCRIPT}" autostart="false"></script><script>  Blazor.start({    webAssembly: {      loadBootResource: function (type, name, defaultUri, integrity) {        if (type == 'dotnetjs') {          return null;        } else {          return fetch(defaultUri, {            cache: 'no-cache',            integrity: integrity,            headers: { 'Custom-Header': 'Custom Value' }          });        }      }    }  });</script>

Standalone Blazor WebAssembly:

<script src="{BLAZOR SCRIPT}" autostart="false"></script><script>  Blazor.start({    loadBootResource: function (type, name, defaultUri, integrity) {      if (type == 'dotnetjs') {        return null;      } else {        return fetch(defaultUri, {          cache: 'no-cache',          integrity: integrity,          headers: { 'Custom-Header': 'Custom Value' }        });      }    }  });</script>

In the preceding example, the{BLAZOR SCRIPT} placeholder is the Blazor script path and file name. For the location of the script, seeASP.NET Core Blazor project structure.

When theloadBootResource function returnsnull, Blazor uses the default loading behavior for the resource. For example, the preceding code returnsnull for thedotnetjs boot resource (dotnet.*.js) because thedotnetjs boot resource must either returnnull for default loading behavior or a URI for the source of thedotnetjs boot resource.

TheloadBootResource function can also return aResponse promise. For an example, seeHost and deploy ASP.NET Core Blazor WebAssembly.

For more information, seeASP.NET Core Blazor WebAssembly caching and integrity check failures.

Control headers in C# code

Control headers at startup in C# code using the following approaches.

In the following examples, aContent Security Policy (CSP) is applied to the app via a CSP header. The{POLICY STRING} placeholder is the CSP policy string. For more information on CSPs, seeEnforce a Content Security Policy for ASP.NET Core Blazor.

Note

Headers can't be set after the response starts. The approaches in this section only set headers before the response starts, so the approaches described here are safe. For more information, seeIHttpContextAccessor/HttpContext in ASP.NET Core Blazor apps.

Server-side and prerendered client-side scenarios

UseASP.NET Core Middleware to control the headers collection.

In theProgram file:

InStartup.Configure ofStartup.cs:

app.Use(async (context, next) =>{    context.Response.Headers.Append("Content-Security-Policy", "{POLICY STRING}");    await next();});

The preceding example uses inline middleware, but you can also create a custom middleware class and call the middleware with an extension method in theProgram file. For more information, seeWrite custom ASP.NET Core middleware.

Client-side development without prerendering

PassStaticFileOptions toMapFallbackToFile that specifies response headers at theOnPrepareResponse stage.

In the server-sideProgram file:

InStartup.Configure ofStartup.cs:

var staticFileOptions = new StaticFileOptions{    OnPrepareResponse = context =>    {        context.Context.Response.Headers.Append("Content-Security-Policy",             "{POLICY STRING}");    }};...app.MapFallbackToFile("index.html", staticFileOptions);

Client-side loading indicators

A loading indicator shows that the app is loading normally and that the user should wait until loading is finished.

Blazor Web App loading indicator

The loading indicator used in Blazor WebAssembly apps isn't present in an app created from the Blazor Web App project template. Usually, a loading indicator isn't desirable for interactive WebAssembly components because Blazor Web Apps prerender client-side components on the server for fast initial load times. For mixed-render-mode situations, the framework or developer code must also be careful to avoid the following problems:

  • Showing multiple loading indicators on the same rendered page.
  • Inadvertently discarding prerendered content while the .NET WebAssembly runtime is loading.

A future release of .NET might provide a framework-based loading indicator. In the meantime, you can add a custom loading indicator to a Blazor Web App.

Per-component Interactive WebAssembly rendering with prerendering

This scenario applies to per-component Interactive WebAssembly rendering (@rendermode InteractiveWebAssembly applied to individual components).

Create aContentLoading component in theLayout folder of the.Client app that callsOperatingSystem.IsBrowser:

  • Whenfalse, display a loading indicator.
  • Whentrue, render the requested component's content.

To load CSS styles for the indicator, add the styles to<head> content with theHeadContent component. For more information, seeControl head content in ASP.NET Core Blazor apps.

Layout/ContentLoading.razor:

@if (!RendererInfo.IsInteractive){    <!-- OPTIONAL ...    <HeadContent>        <style>            ...        </style>    </HeadContent>    -->    <progress aria-label="Content loading…"></progress>}else{    @ChildContent}@code {    [Parameter]    public RenderFragment? ChildContent { get; set; }}
@if (!OperatingSystem.IsBrowser()){    <!-- OPTIONAL ...    <HeadContent>        <style>            ...        </style>    </HeadContent>    -->    <progress aria-label="Content loading…"></progress>}else{    @ChildContent}@code {    [Parameter]    public RenderFragment? ChildContent { get; set; }}

If you didn't already have aLayout folder in the.Client project, add the namespace for theLayout folder to the_Imports.razor file. In the following example, the project's namespace isBlazorSample.Client:

@using BlazorSample.Client.Layout

In a component that adopts Interactive WebAssembly rendering, wrap the component's Razor markup with theContentLoading component. The following example demonstrates the approach with theCounter component of an app created from the Blazor Web App project template.

Pages/Counter.razor:

@page "/counter"@rendermode InteractiveWebAssembly<PageTitle>Counter</PageTitle><ContentLoading>    <h1>Counter</h1>    <p role="status">Current count: @currentCount</p>    <button @onclick="IncrementCount">Click me</button></ContentLoading>@code {    private int currentCount = 0;    private void IncrementCount()    {        currentCount++;    }}

Global Interactive WebAssembly rendering with prerendering

This scenario applies to global Interactive WebAssembly rendering with prerendering (@rendermode="InteractiveWebAssembly" on theHeadOutlet andRoutes components in theApp component).

Create aContentLoading component in theLayout folder of the.Client app that callsRendererInfo.IsInteractive:

  • Whenfalse, display a loading indicator.
  • Whentrue, render the requested component's content.

To load CSS styles for the indicator, add the styles to<head> content with theHeadContent component. For more information, seeControl head content in ASP.NET Core Blazor apps.

Layout/ContentLoading.razor:

@if (!RendererInfo.IsInteractive){    <!-- OPTIONAL ...    <HeadContent>        <style>            ...        </style>    </HeadContent>    -->    <progress aria-label="Content loading…"></progress>}else{    @ChildContent}@code {    [Parameter]    public RenderFragment? ChildContent { get; set; }}
@if (!OperatingSystem.IsBrowser()){    <!-- OPTIONAL ...    <HeadContent>        <style>            ...        </style>    </HeadContent>    -->    <progress aria-label="Content loading…"></progress>}else{    @ChildContent}@code {    [Parameter]    public RenderFragment? ChildContent { get; set; }}

If you didn't already have aLayout folder in the.Client project, add the namespace for theLayout folder to the_Imports.razor file. In the following example, the project's namespace isBlazorSample.Client:

@using BlazorSample.Client.Layout

In theMainLayout component (Layout/MainLayout.razor) of the.Client project, wrap theBody property (@Body) with theContentLoading component:

InLayout/MainLayout.razor:

+ <ContentLoading>    @Body+ </ContentLoading>

Global Interactive WebAssembly rendering without prerendering

This scenario applies to global Interactive WebAssembly rendering without prerendering (@rendermode="new InteractiveWebAssemblyRenderMode(prerender: false)" on theHeadOutlet andRoutes components in theApp component).

Add aJavaScript initializer to the app. In the following JavaScript module file name example, the{ASSEMBLY NAME} placeholder is the assembly name of the server project (for example,BlazorSample). Thewwwroot folder where the module is placed is thewwwroot folder in the server-side project, not the.Client project.

The following example uses aprogress indicator that doesn't indicate the actual progress ofdelivering client-side boot resources to the client, but it serves as a general approach for further development if you want the progress indicator to show the actual progress of loading the app's boot resources.

wwwroot/{ASSEMBLY NAME}.lib.module.js:

export function beforeWebStart(options) {  var progress = document.createElement("progress");  progress.id = 'loadingIndicator';  progress.ariaLabel = 'Blazor loading…';  progress.style = 'position:absolute;top:50%;left:50%;margin-right:-50%;' +    'transform:translate(-50%,-50%);';  document.body.appendChild(progress);}export function afterWebAssemblyStarted(blazor) {  var progress = document.getElementById('loadingIndicator');  progress.remove();}

Due to aframework bug in .NET 8 and 9 (dotnet/aspnetcore #54049), the Blazor script must be manually started. If the server app doesn't already start Blazor manually with a WebAssembly (webAssembly: {...}) configuration, update theApp component in the server project with the following.

InComponents/App.razor, remove the existing Blazor<script> tag:

- <script src="_framework/blazor.web.js"></script>

Replace the<script> tag with the following markup that starts Blazor manually with a WebAssembly (webAssembly: {...}) configuration:

<script src="_framework/blazor.web.js" autostart="false"></script><script>    Blazor.start({        webAssembly: {}    });</script>

If you notice a short delay between the loading indicator removal and the first page render, you can guarantee removal of the indicator after rendering by calling for indicator removal in theOnAfterRenderAsync lifecycle method of either theMainLayout orRoutes components. For more information and a code example, seeDocument an approach for a loading indicator that works with global Interactive WebAssembly without prerendering (dotnet/AspNetCore.Docs #35111).

Blazor WebAssembly app loading progress

The project template contains Scalable Vector Graphics (SVG) and text indicators that show the loading progress of the app.

The progress indicators are implemented with HTML and CSS using two CSS custom properties (variables) provided by Blazor:

  • --blazor-load-percentage: The percentage of app files loaded.
  • --blazor-load-percentage-text: The percentage of app files loaded, rounded to the nearest whole number.

Using the preceding CSS variables, you can create custom progress indicators that match the styling of your app.

In the following example:

  • resourcesLoaded is an instantaneous count of the resources loaded during app startup.
  • totalResources is the total number of resources to load.
const percentage = resourcesLoaded / totalResources * 100;document.documentElement.style.setProperty(  '--blazor-load-percentage', `${percentage}%`);document.documentElement.style.setProperty(  '--blazor-load-percentage-text', `"${Math.floor(percentage)}%"`);

The default round progress indicator is implemented in HTML in thewwwroot/index.html file:

<div>    <svg>        <circle r="40%" cx="50%" cy="50%" />        <circle r="40%" cx="50%" cy="50%" />    </svg>    <div></div></div>

To review the project template markup and styling for the default progress indicators, see the ASP.NET Core reference source:

Note

Documentation links to .NET reference source usually load the repository's default branch, which represents the current development for the next release of .NET. To select a tag for a specific release, use theSwitch branches or tags dropdown list. For more information, seeHow to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205).

Instead of using the default round progress indicator, the following example shows how to implement a linear progress indicator.

Add the following styles towwwroot/css/app.css:

.linear-progress {    background: silver;    width: 50vw;    margin: 20% auto;    height: 1rem;    border-radius: 10rem;    overflow: hidden;    position: relative;}.linear-progress:after {    content: '';    position: absolute;    inset: 0;    background: blue;    scale: var(--blazor-load-percentage, 0%) 100%;    transform-origin: left top;    transition: scale ease-out 0.5s;}

A CSS variable (var(...)) is used to pass the value of--blazor-load-percentage to thescale property of a blue pseudo-element that indicates the loading progress of the app's files. As the app loads,--blazor-load-percentage is updated automatically, which dynamically changes the progress indicator's visual representation.

Inwwwroot/index.html, remove the default SVG round indicator in<div>...</div> and replace it with the following markup:

<div></div>

Configure the .NET WebAssembly runtime

In advanced programming scenarios, theconfigureRuntime function with thedotnet runtime host builder is used to configure the .NET WebAssembly runtime. For example,dotnet.withEnvironmentVariable sets an environment variable that:

  • Configures the .NET WebAssembly runtime.
  • Changes the behavior of a C library.

Note

A documentation request is pending in thedotnet/runtime GitHub repository for more information on environment variables that configure the .NET WebAssembly runtime or affect the behavior of C libraries. Although the documentation request is pending, more information and cross-links to additional resources are available in the request,Question/request for documentation on .NET WASM runtime env vars (dotnet/runtime #98225).

TheconfigureRuntime function can also be used toenable integration with a browser profiler.

For the placeholders in the following examples that set an environment variable:

  • The{BLAZOR SCRIPT} placeholder is the Blazor script path and file name. For the location of the script, seeASP.NET Core Blazor project structure.
  • The{NAME} placeholder is the environment variable's name.
  • The{VALUE} placeholder is the environment variable's value.

Blazor Web App:

<script src="{BLAZOR SCRIPT}" autostart="false"></script><script>  Blazor.start({    webAssembly: {      configureRuntime: dotnet => {        dotnet.withEnvironmentVariable("{NAME}", "{VALUE}");      }    }  });</script>

Standalone Blazor WebAssembly:

<script src="{BLAZOR SCRIPT}" autostart="false"></script><script>  Blazor.start({    configureRuntime: dotnet => {      dotnet.withEnvironmentVariable("{NAME}", "{VALUE}");    }  });</script>

Note

The .NET runtime instance can be accessed using the .NET WebAssembly Runtime API (Blazor.runtime). For example, the app's build configuration can be obtained usingBlazor.runtime.runtimeBuildInfo.buildConfiguration.

For more information on the .NET WebAssembly runtime configuration, see theruntime's TypeScript definition file (dotnet.d.ts) in thedotnet/runtime GitHub repository.

Note

Documentation links to .NET reference source usually load the repository's default branch, which represents the current development for the next release of .NET. To select a tag for a specific release, use theSwitch branches or tags dropdown list. For more information, seeHow to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205).

Disable enhanced navigation and form handling

This section applies to Blazor Web Apps.

To disableenhanced navigation and form handling, setdisableDomPreservation totrue forBlazor.start:

<script src="{BLAZOR SCRIPT}" autostart="false"></script><script>  Blazor.start({    ssr: { disableDomPreservation: true }  });</script>

In the preceding example, the{BLAZOR SCRIPT} placeholder is the Blazor script path and file name. For the location of the script, seeASP.NET Core Blazor project structure.

Additional resources

Collaborate with us on GitHub
The source for this content can be found on GitHub, where you can also create and review issues and pull requests. For more information, seeour contributor guide.

Feedback

Was this page helpful?

YesNoNo

Need help with this topic?

Want to try using Ask Learn to clarify or guide you through this topic?

Suggest a fix?

  • Last updated on

In this article

Was this page helpful?

YesNo
NoNeed help with this topic?

Want to try using Ask Learn to clarify or guide you through this topic?

Suggest a fix?