ASP.NET Core Blazor startup

This article explains how to configure Blazor startup.

Configure a manual start in the wwwroot/index.html file (Blazor WebAssembly) or Pages/_Layout.cshtml file (Blazor Server):

  • Add an autostart="false" attribute and value to the <script> tag for the Blazor script.
  • Place a script that calls Blazor.start after the Blazor <script> tag and inside the closing </body> tag.

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 in Blazor apps. Use of JS initializers often removes the need to manually trigger script functions from the app when using Razor 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 the wwwroot folder.

The module exports either or both of the following conventional functions:

  • 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.
    • In Blazor WebAssembly, beforeStart receives the Blazor WebAssembly options (options in this section's example) and any extensions (extensions in this section's example) added during publishing. For example, options can specify the use of a custom boot resource loader.
    • In Blazor Server, beforeStart receives SignalR circuit start options (options in this section's example).
    • In BlazorWebViews, no options are passed.
  • afterStarted: 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 to afterStarted as an argument (blazor in this section's example).

The following example demonstrates JS initializers for beforeStart and afterStarted. For the filename of the following example:

  • Use the app's assembly name in the filename if the JS initializers are consumed as a static asset in the project. For example, name the file BlazorSample.lib.module.js for a project with an assembly name of BlazorSample. Place the file in the app's wwwroot folder.
  • Use the project's library name or package identifier if the JS initializers are consumed from an RCL. For example, name the file RazorClassLibrary1.lib.module.js for an RCL with a package identifier of RazorClassLibrary1. Place the file in the library's wwwroot folder.
export function beforeStart(options, extensions) {
    console.log("beforeStart");
}

export function afterStarted(blazor) {
    console.log("afterStarted");
}

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 an 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 the Switch branches or tags dropdown list. For more information, see How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205).

Initialize Blazor when the document is ready

The following example starts Blazor when the document is ready:

<body>
    ...

    <script src="_framework/blazor.{webassembly|server}.js" autostart="false"></script>
    <script>
      document.addEventListener("DOMContentLoaded", function() {
        Blazor.start();
      });
    </script>
</body>

The {webassembly|server} placeholder in the preceding markup is either webassembly for a Blazor WebAssembly app (blazor.webassembly.js) or server for a Blazor Server app (blazor.server.js).

Chain to the Promise that results from a manual start

To perform additional tasks, such as JS interop initialization, use then to chain to the Promise that results from a manual Blazor app start:

<body>
    ...

    <script src="_framework/blazor.{webassembly|server}.js" autostart="false"></script>
    <script>
      Blazor.start().then(function () {
        ...
      });
    </script>
</body>

The {webassembly|server} placeholder in the preceding markup is either webassembly for a Blazor WebAssembly app (blazor.webassembly.js) or server for a Blazor Server app (blazor.server.js).

Load boot resources

This section only applies to Blazor WebAssembly apps.

When a Blazor WebAssembly 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 the loadBootResource API. The loadBootResource function overrides the built-in boot resource loading mechanism. Use loadBootResource for the following scenarios:

  • Load static resources, such as timezone data or dotnet.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 each fetch request to a new name.

Note

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

loadBootResource parameters appear in the following table.

Parameter Description
type The type of the resource. Permissable types include: assembly, pdb, dotnetjs, dotnetwasm, and timezonedata. You only need to specify types for custom behaviors. Types not specified to loadBootResource are loaded by the framework per their default loading behaviors.
name The name of the resource.
defaultUri The relative or absolute URI of the resource.
integrity The integrity string representing the expected content in the response.

The loadBootResource function can return a URI string to override the loading process. In the following example, the following files from bin/Release/net5.0/wwwroot/_framework are served from a CDN at https://cdn.example.com/blazorwebassembly/5.0.0/:

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

Inside the closing </body> tag of wwwroot/index.html:

<script src="_framework/blazor.webassembly.js" 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/5.0.0/${name}`;
      }
    }
  });
</script>

To customize more than just the URLs for boot resources, the loadBootResource function can call fetch 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 the integrity parameter.

Inside the closing </body> tag of wwwroot/index.html:

<script src="_framework/blazor.webassembly.js" autostart="false"></script>
<script>
  Blazor.start({
    loadBootResource: function (type, name, defaultUri, integrity) {
      return fetch(defaultUri, { 
        cache: 'no-cache',
        integrity: integrity,
        headers: { 'Custom-Header': 'Custom Value' }
      });
    }
  });
</script>

The loadBootResource function can also return:

Control headers in C# code

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

In the following examples, a Content Security Policy (CSP) is applied to the app via a CSP header. The {POLICY STRING} placeholder is the CSP policy string.

  • In Blazor Server and prerendered Blazor WebAssembly apps, use ASP.NET Core Middleware to control the headers collection.

    In Program.cs:

    app.Use(async (context, next) =>
    {
        context.Response.Headers.Add("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 Program.cs. For more information, see Write custom ASP.NET Core middleware.

  • In hosted Blazor WebAssembly apps that aren't prerendered, pass StaticFileOptions to MapFallbackToFile that specifies response headers at the OnPrepareResponse stage.

    In Program.cs of the Server project:

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

For more information on CSPs, see Enforce a Content Security Policy for ASP.NET Core Blazor.

Additional resources

Configure a manual start in the wwwroot/index.html file (Blazor WebAssembly) or Pages/_Host.cshtml file (Blazor Server):

  • Add an autostart="false" attribute and value to the <script> tag for the Blazor script.
  • Place a script that calls Blazor.start after the Blazor <script> tag and inside the closing </body> tag.

Initialize Blazor when the document is ready

The following example starts Blazor when the document is ready:

<body>
    ...

    <script src="_framework/blazor.{webassembly|server}.js" autostart="false"></script>
    <script>
      document.addEventListener("DOMContentLoaded", function() {
        Blazor.start();
      });
    </script>
</body>

The {webassembly|server} placeholder in the preceding markup is either webassembly for a Blazor WebAssembly app (blazor.webassembly.js) or server for a Blazor Server app (blazor.server.js).

Chain to the Promise that results from a manual start

To perform additional tasks, such as JS interop initialization, use then to chain to the Promise that results from a manual Blazor app start:

<body>
    ...

    <script src="_framework/blazor.{webassembly|server}.js" autostart="false"></script>
    <script>
      Blazor.start().then(function () {
        ...
      });
    </script>
</body>

The {webassembly|server} placeholder in the preceding markup is either webassembly for a Blazor WebAssembly app (blazor.webassembly.js) or server for a Blazor Server app (blazor.server.js).

Load boot resources

This section only applies to Blazor WebAssembly apps.

When a Blazor WebAssembly 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 the loadBootResource API. The loadBootResource function overrides the built-in boot resource loading mechanism. Use loadBootResource for the following scenarios:

  • Load static resources, such as timezone data or dotnet.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 each fetch request to a new name.

Note

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

loadBootResource parameters appear in the following table.

Parameter Description
type The type of the resource. Permissable types include: assembly, pdb, dotnetjs, dotnetwasm, and timezonedata. You only need to specify types for custom behaviors. Types not specified to loadBootResource are loaded by the framework per their default loading behaviors.
name The name of the resource.
defaultUri The relative or absolute URI of the resource.
integrity The integrity string representing the expected content in the response.

The loadBootResource function can return a URI string to override the loading process. In the following example, the following files from bin/Release/net5.0/wwwroot/_framework are served from a CDN at https://cdn.example.com/blazorwebassembly/5.0.0/:

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

Inside the closing </body> tag of wwwroot/index.html:

<script src="_framework/blazor.webassembly.js" 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/5.0.0/${name}`;
      }
    }
  });
</script>

To customize more than just the URLs for boot resources, the loadBootResource function can call fetch 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 the integrity parameter.

Inside the closing </body> tag of wwwroot/index.html:

<script src="_framework/blazor.webassembly.js" autostart="false"></script>
<script>
  Blazor.start({
    loadBootResource: function (type, name, defaultUri, integrity) {
      return fetch(defaultUri, { 
        cache: 'no-cache',
        integrity: integrity,
        headers: { 'Custom-Header': 'Custom Value' }
      });
    }
  });
</script>

The loadBootResource function can also return:

Control headers in C# code

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

In the following examples, a Content Security Policy (CSP) is applied to the app via a CSP header. The {POLICY STRING} placeholder is the CSP policy string.

  • In Blazor Server and prerendered Blazor WebAssembly apps, use ASP.NET Core Middleware to control the headers collection.

    In Startup.Configure of Startup.cs:

    app.Use(async (context, next) =>
    {
        context.Response.Headers.Add("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 Startup.Configure. For more information, see Write custom ASP.NET Core middleware.

  • In hosted Blazor WebAssembly apps that aren't prerendered, pass StaticFileOptions to MapFallbackToFile that specifies response headers at the OnPrepareResponse stage.

    In Startup.Configure (Startup.cs) of the Server project:

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

For more information on CSPs, see Enforce a Content Security Policy for ASP.NET Core Blazor.

Additional resources

Configure a manual start in the wwwroot/index.html file (Blazor WebAssembly) or Pages/_Host.cshtml file (Blazor Server):

  • Add an autostart="false" attribute and value to the <script> tag for the Blazor script.
  • Place a script that calls Blazor.start after the Blazor <script> tag and inside the closing </body> tag.

Initialize Blazor when the document is ready

The following example starts Blazor when the document is ready:

<body>
    ...

    <script src="_framework/blazor.{webassembly|server}.js" autostart="false"></script>
    <script>
      document.addEventListener("DOMContentLoaded", function() {
        Blazor.start();
      });
    </script>
</body>

The {webassembly|server} placeholder in the preceding markup is either webassembly for a Blazor WebAssembly app (blazor.webassembly.js) or server for a Blazor Server app (blazor.server.js).

Chain to the Promise that results from a manual start

To perform additional tasks, such as JS interop initialization, use then to chain to the Promise that results from a manual Blazor app start:

<body>
    ...

    <script src="_framework/blazor.{webassembly|server}.js" autostart="false"></script>
    <script>
      Blazor.start().then(function () {
        ...
      });
    </script>
</body>

The {webassembly|server} placeholder in the preceding markup is either webassembly for a Blazor WebAssembly app (blazor.webassembly.js) or server for a Blazor Server app (blazor.server.js).

Load boot resources

This section only applies to Blazor WebAssembly apps.

When a Blazor WebAssembly 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 the loadBootResource API. The loadBootResource function overrides the built-in boot resource loading mechanism. Use loadBootResource for the following scenarios:

  • Load static resources, such as timezone data or dotnet.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 each fetch request to a new name.

Note

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

loadBootResource parameters appear in the following table.

Parameter Description
type The type of the resource. Permissable types include: assembly, pdb, dotnetjs, dotnetwasm, and timezonedata. You only need to specify types for custom behaviors. Types not specified to loadBootResource are loaded by the framework per their default loading behaviors.
name The name of the resource.
defaultUri The relative or absolute URI of the resource.
integrity The integrity string representing the expected content in the response.

The loadBootResource function can return a URI string to override the loading process. In the following example, the following files from bin/Release/net5.0/wwwroot/_framework are served from a CDN at https://cdn.example.com/blazorwebassembly/3.1.0/:

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

Inside the closing </body> tag of wwwroot/index.html:

<script src="_framework/blazor.webassembly.js" 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/3.1.0/${name}`;
      }
    }
  });
</script>

To customize more than just the URLs for boot resources, the loadBootResource function can call fetch 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 the integrity parameter.

Inside the closing </body> tag of wwwroot/index.html:

<script src="_framework/blazor.webassembly.js" autostart="false"></script>
<script>
  Blazor.start({
    loadBootResource: function (type, name, defaultUri, integrity) {
      return fetch(defaultUri, { 
        cache: 'no-cache',
        integrity: integrity,
        headers: { 'Custom-Header': 'Custom Value' }
      });
    }
  });
</script>

The loadBootResource function can also return:

Control headers in C# code

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

In the following examples, a Content Security Policy (CSP) is applied to the app via a CSP header. The {POLICY STRING} placeholder is the CSP policy string.

  • In Blazor Server, use ASP.NET Core Middleware to control the headers collection.

    In Startup.Configure of Startup.cs:

    app.Use(async (context, next) =>
    {
        context.Response.Headers.Add("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 Program.cs. For more information, see Write custom ASP.NET Core middleware.

  • In hosted Blazor WebAssembly apps, pass StaticFileOptions to MapFallbackToFile that specifies response headers at the OnPrepareResponse stage.

    In Startup.Configure (Startup.cs) of the Server project:

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

For more information on CSPs, see Enforce a Content Security Policy for ASP.NET Core Blazor.

Additional resources

Configure a manual start in the wwwroot/index.html file (Blazor WebAssembly) or Pages/_Host.cshtml file (Blazor Server):

  • Add an autostart="false" attribute and value to the <script> tag for the Blazor script.
  • Place a script that calls Blazor.start after the Blazor <script> tag and inside the closing </body> tag.

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 in Blazor apps. Use of JS initializers often removes the need to manually trigger script functions from the app when using Razor 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 the wwwroot folder.

The module exports either or both of the following conventional functions:

  • 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.
    • In Blazor WebAssembly, beforeStart receives the Blazor WebAssembly options (options in this section's example) and any extensions (extensions in this section's example) added during publishing. For example, options can specify the use of a custom boot resource loader.
    • In Blazor Server, beforeStart receives SignalR circuit start options (options in this section's example).
    • In BlazorWebViews, no options are passed.
  • afterStarted: 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 to afterStarted as an argument (blazor in this section's example).

The following example demonstrates JS initializers for beforeStart and afterStarted. For the filename of the following example:

  • Use the app's assembly name in the filename if the JS initializers are consumed as a static asset in the project. For example, name the file BlazorSample.lib.module.js for a project with an assembly name of BlazorSample. Place the file in the app's wwwroot folder.
  • Use the project's library name or package identifier if the JS initializers are consumed from an RCL. For example, name the file RazorClassLibrary1.lib.module.js for an RCL with a package identifier of RazorClassLibrary1. Place the file in the library's wwwroot folder.
export function beforeStart(options, extensions) {
    console.log("beforeStart");
}

export function afterStarted(blazor) {
    console.log("afterStarted");
}

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 an 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 the Switch branches or tags dropdown list. For more information, see How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205).

Initialize Blazor when the document is ready

The following example starts Blazor when the document is ready:

<body>
    ...

    <script src="_framework/blazor.{webassembly|server}.js" autostart="false"></script>
    <script>
      document.addEventListener("DOMContentLoaded", function() {
        Blazor.start();
      });
    </script>
</body>

The {webassembly|server} placeholder in the preceding markup is either webassembly for a Blazor WebAssembly app (blazor.webassembly.js) or server for a Blazor Server app (blazor.server.js).

Chain to the Promise that results from a manual start

To perform additional tasks, such as JS interop initialization, use then to chain to the Promise that results from a manual Blazor app start:

<body>
    ...

    <script src="_framework/blazor.{webassembly|server}.js" autostart="false"></script>
    <script>
      Blazor.start().then(function () {
        ...
      });
    </script>
</body>

The {webassembly|server} placeholder in the preceding markup is either webassembly for a Blazor WebAssembly app (blazor.webassembly.js) or server for a Blazor Server app (blazor.server.js).

Load boot resources

This section only applies to Blazor WebAssembly apps.

When a Blazor WebAssembly 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 the loadBootResource API. The loadBootResource function overrides the built-in boot resource loading mechanism. Use loadBootResource for the following scenarios:

  • Load static resources, such as timezone data or dotnet.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 each fetch request to a new name.

Note

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

loadBootResource parameters appear in the following table.

Parameter Description
type The type of the resource. Permissable types include: assembly, pdb, dotnetjs, dotnetwasm, and timezonedata. You only need to specify types for custom behaviors. Types not specified to loadBootResource are loaded by the framework per their default loading behaviors.
name The name of the resource.
defaultUri The relative or absolute URI of the resource.
integrity The integrity string representing the expected content in the response.

The loadBootResource function can return a URI string to override the loading process. In the following example, the following files from bin/Release/net5.0/wwwroot/_framework are served from a CDN at https://cdn.example.com/blazorwebassembly/5.0.0/:

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

Inside the closing </body> tag of wwwroot/index.html:

<script src="_framework/blazor.webassembly.js" 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/5.0.0/${name}`;
      }
    }
  });
</script>

To customize more than just the URLs for boot resources, the loadBootResource function can call fetch 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 the integrity parameter.

Inside the closing </body> tag of wwwroot/index.html:

<script src="_framework/blazor.webassembly.js" autostart="false"></script>
<script>
  Blazor.start({
    loadBootResource: function (type, name, defaultUri, integrity) {
      return fetch(defaultUri, { 
        cache: 'no-cache',
        integrity: integrity,
        headers: { 'Custom-Header': 'Custom Value' }
      });
    }
  });
</script>

The loadBootResource function can also return:

Control headers in C# code

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

In the following examples, a Content Security Policy (CSP) is applied to the app via a CSP header. The {POLICY STRING} placeholder is the CSP policy string.

  • In Blazor Server and prerendered Blazor WebAssembly apps, use ASP.NET Core Middleware to control the headers collection.

    In Program.cs:

    app.Use(async (context, next) =>
    {
        context.Response.Headers.Add("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 Program.cs. For more information, see Write custom ASP.NET Core middleware.

  • In hosted Blazor WebAssembly apps that aren't prerendered, pass StaticFileOptions to MapFallbackToFile that specifies response headers at the OnPrepareResponse stage.

    In Program.cs of the Server project:

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

For more information on CSPs, see Enforce a Content Security Policy for ASP.NET Core Blazor.

Loading progress indicators

This section only applies to Blazor WebAssembly apps.

The Blazor WebAssembly 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 WebAssembly:

  • --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 progress indicators are implemented in HTML in the wwwroot/index.html file:

<svg class="loading-progress">
    <circle r="40%" cx="50%" cy="50%" />
    <circle r="40%" cx="50%" cy="50%" />
</svg>
<div class="loading-progress-text"></div>

To review the Blazor WebAssembly 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 the Switch branches or tags dropdown list. For more information, see How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205).

Additional resources