- Vscode Blazor Extension
- Debugging Blazor App
- Vs Code Blazor Wasm
- Debug Blazor Visual Studio Code
- Blazer Page App
The following steps explain how to install the Syncfusion Blazor extensions from Visual Studio Code Extensions. Open Visual Studio Code. Go to View Extensions, and open Manage Extensions. Type “Syncfusion Blazor” in the search box. Click the Install button on the “Blazor Project Templates - Syncfusion” extension. Blazor Studio is a Visual Studio Extension with templates that allows you to easily stand up a new web REST API and Blazor back-office web application in only a few minutes - saving you hours, and even days of work for each project. The sites generated by Blazor Studio include the following features.
-->A Progressive Web Application (PWA) is usually a Single Page Application (SPA) that uses modern browser APIs and capabilities to behave like a desktop app. Blazor WebAssembly is a standards-based client-side web app platform, so it can use any browser API, including PWA APIs required for the following capabilities:
Before using the Syncfusion Blazor Code Generator, check whether the Syncfusion Blazor Extension is installed or not in Visual Studio Extension Manager by clicking on the Extensions - Manage Extensions - Installed. If it is not installed, please install the Syncfusion Blazor. The following steps illustrate how to download and install the Syncfusion Blazor Template Studio with the Code Generator extension from the Visual Studio Marketplace. Note: Syncfusion Blazor Code Generator was shipped within the Syncfusion Template Studio. Download the Syncfusion Blazor Template Studio from the Visual Studio Marketplace. Visual Studio; Visual Studio Code /.NET Core CLI; When creating a new Blazor WebAssembly App in the Create a New Project dialog, select the Progressive Web Application check box. Use the following command to create a PWA project in a command shell with the -pwa switch. Dotnet new blazorwasm -o MyBlazorPwa -pwa.
- Working offline and loading instantly, independent of network speed.
- Running in its own app window, not just a browser window.
- Being launched from the host's operating system start menu, dock, or home screen.
- Receiving push notifications from a backend server, even while the user isn't using the app.
- Automatically updating in the background.
The word progressive is used to describe such apps because:
- A user might first discover and use the app within their web browser like any other SPA.
- Later, the user progresses to installing it in their OS and enabling push notifications.
Create a project from the PWA template
When creating a new Blazor WebAssembly App in the Create a New Project dialog, select the Progressive Web Application check box:
Use the following command to create a PWA project in a command shell with the --pwa
switch:
In the preceding command, the -o|--output
option creates a new folder for the app named MyBlazorPwa
.
Optionally, PWA can be configured for an app created from the ASP.NET Core Hosted template. The PWA scenario is independent of the hosting model.
Convert an existing Blazor WebAssembly app into a PWA
Convert an existing Blazor WebAssembly app into a PWA following the guidance in this section.
In the app's project file:
Add the following
ServiceWorkerAssetsManifest
property to aPropertyGroup
:Add the following
ServiceWorker
item to anItemGroup
:
To obtain static assets, use one of the following approaches:
Create a separate, new PWA project with the
dotnet new
command in a command shell:In the preceding command, the
-o|--output
option creates a new folder for the app namedMyBlazorPwa
.If you aren't converting an app for the latest release, pass the
-f|--framework
option. The following example creates the app for ASP.NET Core version 3.1:Navigate to the ASP.NET Core GitHub repository at the following URL, which links to
main
branch reference source and assets. Select the release that you're working with from the Switch branches or tags drop-down list that applies to your app.Note
Documentation links to the ASP.NET Core reference source load the repository's
main
branch, which represents the product unit's current development for the next release of ASP.NET Core. To select the branch for a different release, use the Switch branches or tags drop-down list to select the branch. For example, select therelease/5.0
branch for the ASP.NET Core 5.0 release.
Create a separate, new PWA project with the
dotnet new
command in a command shell. Pass the-f|--framework
option to select the version. The following example creates the app for ASP.NET Core version 3.1:In the preceding command, the
-o|--output
option creates a new folder for the app namedMyBlazorPwa
.Navigate to the ASP.NET Core GitHub repository at the following URL, which links to 3.1 release reference source and assets:
Note
The URL for Blazor WebAssembly project template changed after the release of ASP.NET Core 3.1. Reference assets for any release are available from the ASP.NET Core reference source. Select the release that you're working with from the Switch branches or tags drop-down list that applies to your app.
Note
Documentation links to the ASP.NET Core reference source load the repository's
main
branch, which represents the product unit's current development for the next release of ASP.NET Core. To select the branch for a different release, use the Switch branches or tags drop-down list to select the branch. For example, select therelease/5.0
branch for the ASP.NET Core 5.0 release.
From the source wwwroot
folder either in the app that you created or from the reference assets in the dotnet/aspnetcore
GitHub repository, copy the following files into the app's wwwroot
folder:
icon-512.png
manifest.json
service-worker.js
service-worker.published.js
In the app's wwwroot/index.html
file:
Add
<link>
elements for the manifest and app icon:Add the following
<script>
tag inside the closing</body>
tag immediately after theblazor.webassembly.js
script tag:
Installation and app manifest
When visiting an app created using the PWA template, users have the option of installing the app into their OS's start menu, dock, or home screen. The way this option is presented depends on the user's browser. When using desktop Chromium-based browsers, such as Edge or Chrome, an Add button appears within the URL bar. After the user selects the Add button, they receive a confirmation dialog:
On iOS, visitors can install the PWA using Safari's Share button and its Add to Homescreen option. On Chrome for Android, users should select the Menu button in the upper-right corner, followed by Add to Home screen.
Once installed, the app appears in its own window without an address bar:
To customize the window's title, color scheme, icon, or other details, see the manifest.json
file in the project's wwwroot
directory. The schema of this file is defined by web standards. For more information, see MDN web docs: Web App Manifest.
Offline support
By default, apps created using the PWA template option have support for running offline. A user must first visit the app while they're online. The browser automatically downloads and caches all of the resources required to operate offline.
Important
Development support would interfere with the usual development cycle of making changes and testing them. Therefore, offline support is only enabled for published apps.
Warning
If you intend to distribute an offline-enabled PWA, there are several important warnings and caveats. These scenarios are inherent to offline PWAs and not specific to Blazor. Be sure to read and understand these caveats before making assumptions about how your offline-enabled app will work.
To see how offline support works:
Publish the app. For more information, see Host and deploy ASP.NET Core Blazor.
Deploy the app to a server that supports HTTPS, and access the app in a browser at its secure HTTPS address.
Open the browser's dev tools and verify that a Service Worker is registered for the host on the Application tab:
Reload the page and examine the Network tab. Service Worker or memory cache are listed as the sources for all of the page's assets:
To verify that the browser isn't dependent on network access to load the app, either:
- Shut down the web server and see how the app continues to function normally, which includes page reloads. Likewise, the app continues to function normally when there's a slow network connection.
- Instruct the browser to simulate offline mode in the Network tab:
Offline support using a service worker is a web standard, not specific to Blazor. For more information on service workers, see MDN web docs: Service Worker API. To learn more about common usage patterns for service workers, see Google Web: The Service Worker Lifecycle.
Blazor's PWA template produces two service worker files:
wwwroot/service-worker.js
, which is used during development.wwwroot/service-worker.published.js
, which is used after the app is published.
To share logic between the two service worker files, consider the following approach:
- Add a third JavaScript file to hold the common logic.
- Use
self.importScripts
to load the common logic into both service worker files.
Cache-first fetch strategy
The built-in service-worker.published.js
service worker resolves requests using a cache-first strategy. This means that the service worker prefers to return cached content, regardless of whether the user has network access or newer content is available on the server.
The cache-first strategy is valuable because:
It ensures reliability. Network access isn't a boolean state. A user isn't simply online or offline:
- The user's device may assume it's online, but the network might be so slow as to be impractical to wait for.
- The network might return invalid results for certain URLs, such as when there's a captive WIFI portal that's currently blocking or redirecting certain requests.
This is why the browser's
navigator.onLine
API isn't reliable and shouldn't be depended upon.It ensures correctness. When building a cache of offline resources, the service worker uses content hashing to guarantee it has fetched a complete and self-consistent snapshot of resources at a single instant in time. This cache is then used as an atomic unit. There's no point asking the network for newer resources, since the only versions required are the ones already cached. Anything else risks inconsistency and incompatibility (for example, trying to use versions of .NET assemblies that weren't compiled together).
Background updates
As a mental model, you can think of an offline-first PWA as behaving like a mobile app that can be installed. The app starts up immediately regardless of network connectivity, but the installed app logic comes from a point-in-time snapshot that might not be the latest version.
The Blazor PWA template produces apps that automatically try to update themselves in the background whenever the user visits and has a working network connection. The way this works is as follows:
- During compilation, the project generates a service worker assets manifest. By default, this is called
service-worker-assets.js
. The manifest lists all the static resources that the app requires to function offline, such as .NET assemblies, JavaScript files, and CSS, including their content hashes. The resource list is loaded by the service worker so that it knows which resources to cache. - Each time the user visits the app, the browser re-requests
service-worker.js
andservice-worker-assets.js
in the background. The files are compared byte-for-byte with the existing installed service worker. If the server returns changed content for either of these files, the service worker attempts to install a new version of itself. - When installing a new version of itself, the service worker creates a new, separate cache for offline resources and starts populating the cache with resources listed in
service-worker-assets.js
. This logic is implemented in theonInstall
function insideservice-worker.published.js
. - The process completes successfully when all of the resources are loaded without error and all content hashes match. If successful, the new service worker enters a waiting for activation state. As soon as the user closes the app (no remaining app tabs or windows), the new service worker becomes active and is used for subsequent app visits. The old service worker and its cache are deleted.
- If the process doesn't complete successfully, the new service worker instance is discarded. The update process is attempted again on the user's next visit, when hopefully the client has a better network connection that can complete the requests.
Customize this process by editing the service worker logic. None of the preceding behavior is specific to Blazor but is merely the default experience provided by the PWA template option. For more information, see MDN web docs: Service Worker API.
How requests are resolved
As described in the Cache-first fetch strategy section, the default service worker uses a cache-first strategy, meaning that it tries to serve cached content when available. If there is no content cached for a certain URL, for example when requesting data from a backend API, the service worker falls back on a regular network request. The network request succeeds if the server is reachable. This logic is implemented inside onFetch
function within service-worker.published.js
.
If the app's Razor components rely on requesting data from backend APIs and you want to provide a friendly user experience for failed requests due to network unavailability, implement logic within the app's components. For example, use try/catch
around HttpClient requests.
Support server-rendered pages
Consider what happens when the user first navigates to a URL such as /counter
or any other deep link in the app. In these cases, you don't want to return content cached as /counter
, but instead need the browser to load the content cached as /index.html
to start up your Blazor WebAssembly app. These initial requests are known as navigation requests, as opposed to:
subresource
requests for images, stylesheets, or other files.fetch/XHR
requests for API data.
The default service worker contains special-case logic for navigation requests. The service worker resolves the requests by returning the cached content for /index.html
, regardless of the requested URL. This logic is implemented in the onFetch
function inside service-worker.published.js
.
If your app has certain URLs that must return server-rendered HTML, and not serve /index.html
from the cache, then you need to edit the logic in your service worker. If all URLs containing /Identity/
need to be handled as regular online-only requests to the server, then modify service-worker.published.js
onFetch
logic. Locate the following code:
Change the code to the following:
If you don't do this, then regardless of network connectivity, the service worker intercepts requests for such URLs and resolves them using /index.html
.
Add additional endpoints for external authentication providers to the check. In the following example, /signin-google
for Google authentication is added to the check:
No action is required for the Development environment, where content is always fetched from the network.
Control asset caching
If your project defines the ServiceWorkerAssetsManifest
MSBuild property, Blazor's build tooling generates a service worker assets manifest with the specified name. The default PWA template produces a project file containing the following property:
The file is placed in the wwwroot
output directory, so the browser can retrieve this file by requesting /service-worker-assets.js
. To see the contents of this file, open /bin/Debug/{TARGET FRAMEWORK}/wwwroot/service-worker-assets.js
in a text editor. However, don't edit the file, as it's regenerated on each build.
By default, this manifest lists:
- Any Blazor-managed resources, such as .NET assemblies and the .NET WebAssembly runtime files required to function offline.
- All resources for publishing to the app's
wwwroot
directory, such as images, stylesheets, and JavaScript files, including static web assets supplied by external projects and NuGet packages.
You can control which of these resources are fetched and cached by the service worker by editing the logic in onInstall
in service-worker.published.js
. By default, the service worker fetches and caches files matching typical web filename extensions such as .html
, .css
, .js
, and .wasm
, plus file types specific to Blazor WebAssembly (.dll
, .pdb
).
To include additional resources that aren't present in the app's wwwroot
directory, define extra MSBuild ItemGroup
entries, as shown in the following example:
The AssetUrl
metadata specifies the base-relative URL that the browser should use when fetching the resource to cache. This can be independent of its original source file name on disk.
Important
Adding a ServiceWorkerAssetsManifestItem
doesn't cause the file to be published in the app's wwwroot
directory. The publish output must be controlled separately. The ServiceWorkerAssetsManifestItem
only causes an additional entry to appear in the service worker assets manifest.
Push notifications
Like any other PWA, a Blazor WebAssembly PWA can receive push notifications from a backend server. The server can send push notifications at any time, even when the user isn't actively using the app. For example, push notifications can be sent when a different user performs a relevant action.
The mechanism for sending a push notification is entirely independent of Blazor WebAssembly, since it's implemented by the backend server which can use any technology. If you want to send push notifications from an ASP.NET Core server, consider using a technique similar to the approach taken in the Blazing Pizza workshop.
The mechanism for receiving and displaying a push notification on the client is also independent of Blazor WebAssembly, since it's implemented in the service worker JavaScript file. For an example, see the approach used in the Blazing Pizza workshop.
Caveats for offline PWAs
Not all apps should attempt to support offline use. Offline support adds significant complexity, while not always being relevant for the use cases required.
Offline support is usually relevant only:
- If the primary data store is local to the browser. For example, the approach is relevant in an app with a UI for an IoT device that stores data in
localStorage
or IndexedDB. - If the app performs a significant amount of work to fetch and cache the backend API data relevant to each user so that they can navigate through the data offline. If the app must support editing, a system for tracking changes and synchronizing data with the backend must be built.
- If the goal is to guarantee that the app loads immediately regardless of network conditions. Implement a suitable user experience around backend API requests to show the progress of requests and behave gracefully when requests fail due to network unavailability.
Additionally, offline-capable PWAs must deal with a range of additional complications. Developers should carefully familiarize themselves with the caveats in the following sections.
Offline support only when published
During development you typically want to see each change reflected immediately in the browser without going through a background update process. Therefore, Blazor's PWA template enables offline support only when published.
When building an offline-capable app, it's not enough to test the app in the Development environment. You must test the app in its published state to understand how it responds to different network conditions.
Update completion after user navigation away from app
Updates don't complete until the user has navigated away from the app in all tabs. As explained in the Background updates section, after you deploy an update to the app, the browser fetches the updated service worker files to begin the update process.
What surprises many developers is that, even when this update completes, it does not take effect until the user has navigated away in all tabs. It is not sufficient to refresh the tab displaying the app, even if it's the only tab displaying the app. Until your app is completely closed, the new service worker remains in the waiting to activate status. This is not specific to Blazor, but rather is a standard web platform behavior.
This commonly troubles developers who are trying to test updates to their service worker or offline cached resources. If you check in the browser's developer tools, you may see something like the following:
For as long as the list of 'clients,' which are tabs or windows displaying your app, is nonempty, the worker continues waiting. The reason service workers do this is to guarantee consistency. Consistency means that all resources are fetched from the same atomic cache.
When testing changes, you may find it convenient to click the 'skipWaiting' link as shown in the preceding screenshot, then reload the page. You can automate this for all users by coding your service worker to skip the 'waiting' phase and immediately activate on update. If you skip the waiting phase, you're giving up the guarantee that resources are always fetched consistently from the same cache instance.
Users may run any historical version of the app
Web developers habitually expect that users only run the latest deployed version of their web app, since that's normal within the traditional web distribution model. However, an offline-first PWA is more akin to a native mobile app, where users aren't necessarily running the latest version.
As explained in the Background updates section, after you deploy an update to your app, each existing user continues to use a previous version for at least one further visit because the update occurs in the background and isn't activated until the user thereafter navigates away. Plus, the previous version being used isn't necessarily the previous one you deployed. The previous version can be any historical version, depending on when the user last completed an update.
This can be an issue if the frontend and backend parts of your app require agreement about the schema for API requests. You must not deploy backward-incompatible API schema changes until you can be sure that all users have upgraded. Alternatively, block users from using incompatible older versions of the app. This scenario requirement is the same as for native mobile apps. If you deploy a breaking change in server APIs, the client app is broken for users who haven't yet updated.
If possible, don't deploy breaking changes to your backend APIs. If you must do so, consider using standard Service Worker APIs such as ServiceWorkerRegistration to determine whether the app is up-to-date, and if not, to prevent usage.
Interference with server-rendered pages
As described in the Support server-rendered pages section, if you want to bypass the service worker's behavior of returning /index.html
contents for all navigation requests, edit the logic in your service worker.
All service worker asset manifest contents are cached by default
As described in the Control asset caching section, the file service-worker-assets.js
is generated during build and lists all assets the service worker should fetch and cache.
Since this list by default includes everything emitted to wwwroot
, including content supplied by external packages and projects, you must be careful not to put too much content there. If the wwwroot
directory contains millions of images, the service worker tries to fetch and cache them all, consuming excessive bandwidth and most likely not completing successfully.
Implement arbitrary logic to control which subset of the manifest's contents should be fetched and cached by editing the onInstall
function in service-worker.published.js
.
Interaction with authentication
The PWA template can be used in conjunction with authentication. An offline-capable PWA can also support authentication when the user has initial network connectivity.
When a user doesn't have network connectivity, they can't authenticate or obtain access tokens. By default, attempting to visit the login page without network access results in a 'network error' message. You must design a UI flow that allows the user perform useful tasks while offline without attempting to authenticate the user or obtain access tokens. Alternatively, you can design the app to gracefully fail when the network isn't available. If the app can't be designed to handle these scenarios, you might not want to enable offline support.
When an app that's designed for online and offline use is online again:
- The app might need to provision a new access token.
- The app must detect if a different user is signed into the service so that it can apply operations to the user's account that were made while they were offline.
To create an offline PWA app that interacts with authentication:
- Replace the AccountClaimsPrincipalFactory<TAccount> with a factory that stores the last signed-in user and uses the stored user when the app is offline.
- Queue operations while the app is offline and apply them when the app returns online.
- During sign out, clear the stored user.
The CarChecker
sample app demonstrates the preceding approaches. See the following parts of the app:
OfflineAccountClaimsPrincipalFactory
(Client/Data/OfflineAccountClaimsPrincipalFactory.cs
)LocalVehiclesStore
(Client/Data/LocalVehiclesStore.cs
)LoginStatus
component (Client/Shared/LoginStatus.razor
)
Additional resources
-->Blazor WebAssembly apps can be debugged using the browser dev tools in Chromium-based browsers (Edge/Chrome). You can also debug your app using the following integrated development environments (IDEs):
- Visual Studio
- Visual Studio for Mac
- Visual Studio Code
Available scenarios include:
- Set and remove breakpoints.
- Run the app with debugging support in IDEs.
- Single-step through the code.
- Resume code execution with a keyboard shortcut in IDEs.
- In the Locals window, observe the values of local variables.
- See the call stack, including call chains between JavaScript and .NET.
For now, you can't:
- Break on unhandled exceptions.
- Hit breakpoints during app startup before the debug proxy is running. This includes breakpoints in
Program.Main
(Program.cs
) and breakpoints in theOnInitialized{Async}
lifecycle methods of components that are loaded by the first page requested from the app. - Debug in non-local scenarios (for example, Windows Subsystem for Linux (WSL) or Visual Studio Codespaces).
- Automatically rebuild the backend
*Server*
app of a hosted Blazor WebAssembly solution during debugging, for example by running the app withdotnet watch run
.
Prerequisites
Debugging requires either of the following browsers:
- Google Chrome (version 70 or later) (default)
- Microsoft Edge (version 80 or later)
Ensure that firewalls or proxies don't block communication with the debug proxy (NodeJS
process). For more information, see the Firewall configuration section.
Visual Studio Code users require the following extensions:
- Blazor WASM Debugging Extension (when using the C# for Visual Studio Code Extension version 1.23.9 or later)
After opening a project in VS Code, you may receive a notification that additional setup is required to enable debugging. If requested, install the required extensions from the Visual Studio Marketplace. To inspect the installed extensions, open View > Extensions from the menu bar or select the Extensions icon in the Activity sidebar.
Visual Studio for Mac requires version 8.8 (build 1532) or later:
- Install the latest release of Visual Studio for Mac by selecting the Download Visual Studio for Mac button at Microsoft: Visual Studio for Mac.
- Select the Preview channel from within Visual Studio. For more information, see Install a preview version of Visual Studio for Mac.
Note
Apple Safari on macOS isn't currently supported.
Enable debugging
To enable debugging for an existing Blazor WebAssembly app, update the launchSettings.json
file in the startup project to include the following inspectUri
property in each launch profile:
Once updated, the launchSettings.json
file should look similar to the following example:
The inspectUri
property:
- Enables the IDE to detect that the app is a Blazor WebAssembly app.
- Instructs the script debugging infrastructure to connect to the browser through Blazor's debugging proxy.
The placeholder values for the WebSockets protocol (wsProtocol
), host (url.hostname
), port (url.port
), and inspector URI on the launched browser (browserInspectUri
) are provided by the framework.
To debug a Blazor WebAssembly app in Visual Studio:
Create a new hosted Blazor WebAssembly solution.
Press F5 to run the app in the debugger.
Note
Start Without Debugging (Ctrl+F5) isn't supported. When the app is run in Debug configuration, debugging overhead always results in a small performance reduction.
In the
*Client*
app, set a breakpoint on thecurrentCount++;
line inPages/Counter.razor
.In the browser, navigate to
Counter
page and select the Click me button to hit the breakpoint.In Visual Studio, inspect the value of the
currentCount
field in the Locals window.Press F5 to continue execution.
While debugging a Blazor WebAssembly app, you can also debug server code:
- Set a breakpoint in the
Pages/FetchData.razor
page in OnInitializedAsync. - Set a breakpoint in the
WeatherForecastController
in theGet
action method. - Browse to the
Fetch Data
page to hit the first breakpoint in theFetchData
component just before it issues an HTTP request to the server. - Press F5 to continue execution and then hit the breakpoint on the server in the
WeatherForecastController
. - Press F5 again to let execution continue and see the weather forecast table rendered in the browser.
Note
Breakpoints are not hit during app startup before the debug proxy is running. This includes breakpoints in Program.Main
(Program.cs
) and breakpoints in the OnInitialized{Async}
lifecycle methods of components that are loaded by the first page requested from the app.
If the app is hosted at a different app base path than /
, update the following properties in Properties/launchSettings.json
to reflect the app's base path:
applicationUrl
:inspectUri
of each profile:
The placeholders in the preceding settings:
{INSECURE PORT}
: The insecure port. A random value is provided by default, but a custom port is permitted.{APP BASE PATH}
: The app's base path.{SECURE PORT}
: The secure port. A random value is provided by default, but a custom port is permitted.{PROFILE 1, 2, ... N}
: Launch settings profiles. Usually, an app specifies more than one profile by default (for example, a profile for IIS Express and a project profile, which is used by Kestrel server).
In the following examples, the app is hosted at /OAT
with an app base path configured in wwwroot/index.html
as <base href='/OAT/'>
:
For information on using a custom app base path for Blazor WebAssembly apps, see Host and deploy ASP.NET Core Blazor.
Debug standalone Blazor WebAssembly
For information on configuring VS Code assets in the .vscode
folder, see the Linux operating system guidance in Tooling for ASP.NET Core Blazor.
Open the standalone Blazor WebAssembly app in VS Code.
You may receive a notification that additional setup is required to enable debugging:
Additional setup is required to debug Blazor WebAssembly applications.
If you receive the notification:
- Confirm that the latest C# for Visual Studio Code Extension is installed. To inspect the installed extensions, open View > Extensions from the menu bar or select the Extensions icon in the Activity sidebar.
- When using the C# for Visual Studio Code Extensionversion 1.23.9 or later, confirm that the latest Blazor WASM Debugging Extension is installed. To inspect the installed extensions, open View > Extensions from the menu bar or select the Extensions icon in the Activity sidebar.
- Confirm that JavaScript preview debugging is enabled. Open the settings from the menu bar (File > Preferences > Settings). Search using the keywords
debug preview
. In the search results, set or confirm that the check box for Debug > JavaScript: Use Preview is checked. If the option to enable preview debugging isn't present, either upgrade to the latest version of VS Code or install the JavaScript Debugger Extension (VS Code versions 1.46 or earlier). - Reload the window.
Start debugging using the F5 keyboard shortcut or the menu item.
Note
Start Without Debugging (Ctrl+F5) isn't supported. When the app is run in Debug configuration, debugging overhead always results in a small performance reduction.
When prompted, select the Blazor WebAssembly Debug option to start debugging.
The standalone app is launched, and a debugging browser is opened.
In the
*Client*
app, set a breakpoint on thecurrentCount++;
line inPages/Counter.razor
.In the browser, navigate to
Counter
page and select the Click me button to hit the breakpoint.
Note
Breakpoints are not hit during app startup before the debug proxy is running. This includes breakpoints in Program.Main
(Program.cs
) and breakpoints in the OnInitialized{Async}
lifecycle methods of components that are loaded by the first page requested from the app.
Debug hosted Blazor WebAssembly
Open the
Client
project folder of the hosted Blazor solution folder in VS Code.If there's no launch configuration set for the project, the following notification appears. Select Yes.
Required assets to build and debug are missing from '{APPLICATION NAME}'. Add them?
For information on configuring VS Code assets in the
.vscode
folder, see the Linux operating system guidance in Tooling for ASP.NET Core Blazor.In the command palette at the top of the window, select the Server project within the hosted solution.
A launch.json
file is generated with the launch configuration for launching the debugger.
Attach to an existing debugging session
To attach to a running Blazor app, create a launch.json
file with the following configuration:
Note
Attaching to a debugging session is only supported for standalone apps. To use full-stack debugging, you must launch the app from VS Code.
Launch configuration options
The following launch configuration options are supported for the blazorwasm
debug type (.vscode/launch.json
).
Option | Description |
---|---|
request | Use launch to launch and attach a debugging session to a Blazor WebAssembly app or attach to attach a debugging session to an already-running app. |
url | The URL to open in the browser when debugging. Defaults to https://localhost:5001 . |
browser | The browser to launch for the debugging session. Set to edge or chrome . Defaults to chrome . |
trace | Used to generate logs from the JS debugger. Set to true to generate logs. |
hosted | Must be set to true if launching and debugging a hosted Blazor WebAssembly app. |
webRoot | Specifies the absolute path of the web server. Should be set if an app is served from a sub-route. |
timeout | The number of milliseconds to wait for the debugging session to attach. Defaults to 30,000 milliseconds (30 seconds). |
program | A reference to the executable to run the server of the hosted app. Must be set if hosted is true . |
cwd | The working directory to launch the app under. Must be set if hosted is true . |
env | The environment variables to provide to the launched process. Only applicable if hosted is set to true . |
Example launch configurations
Launch and debug a standalone Blazor WebAssembly app
Attach to a running app at a specified URL
Launch and debug a hosted Blazor WebAssembly app with Microsoft Edge
Browser configuration defaults to Google Chrome. When using Microsoft Edge for debugging, set browser
to edge
. To use Google Chrome, either don't set the browser
option or set the option's value to chrome
.
In the preceding example, MyHostedApp.Server.dll
is the Server app's assembly. The .vscode
folder is located in the solution's folder next to the Client
, Server
, and Shared
folders.
To debug a Blazor WebAssembly app in Visual Studio for Mac:
Create a new ASP.NET Core hosted Blazor WebAssembly app.
Press ⌘+↩ to run the app in the debugger.
Note
Start Without Debugging (⌥+⌘+↩) isn't supported. When the app is run in Debug configuration, debugging overhead always results in a small performance reduction.
Important
Google Chrome or Microsoft Edge must be the selected browser for the debugging session.
In the
*Client*
app, set a breakpoint on thecurrentCount++;
line inPages/Counter.razor
.In the browser, navigate to
Counter
page and select the Click me button to hit the breakpoint:In Visual Studio, inspect the value of the
currentCount
field in the Locals window.Press ⌘+↩ to continue execution.
Vscode Blazor Extension
While debugging a Blazor WebAssembly app, you can also debug server code:
- Set a breakpoint in the
Pages/FetchData.razor
page in OnInitializedAsync. - Set a breakpoint in the
WeatherForecastController
in theGet
action method. - Browse to the
Fetch Data
page to hit the first breakpoint in theFetchData
component just before it issues an HTTP request to the server. - Press ⌘+↩ to continue execution and then hit the breakpoint on the server in the
WeatherForecastController
. - Press ⌘+↩ again to let execution continue and see the weather forecast table rendered in the browser.
Note
Breakpoints are not hit during app startup before the debug proxy is running. This includes breakpoints in Program.Main
(Program.cs
) and breakpoints in the OnInitialized{Async}
lifecycle methods of components that are loaded by the first page requested from the app.
For more information, see Debugging with Visual Studio for Mac.
Debug in the browser
The guidance in this section applies to Google Chrome and Microsoft Edge running on Windows.
Run a Debug build of the app in the Development environment.
Launch a browser and navigate to the app's URL (for example,
https://localhost:5001
).In the browser, attempt to commence remote debugging by pressing Shift+Alt+d.
The browser must be running with remote debugging enabled, which isn't the default. If remote debugging is disabled, an Unable to find debuggable browser tab error page is rendered with instructions for launching the browser with the debugging port open. Follow the instructions for your browser, which opens a new browser window. Close the previous browser window.
Once the browser is running with remote debugging enabled, the debugging keyboard shortcut in the previous step opens a new debugger tab.
After a moment, the Sources tab shows a list of the app's .NET assemblies within the
file://
node.In component code (
.razor
files) and C# code files (.cs
), breakpoints that you set are hit when code executes. After a breakpoint is hit, single-step (F10) through the code or resume (F8) code execution normally.
Blazor provides a debugging proxy that implements the Chrome DevTools Protocol and augments the protocol with .NET-specific information. When debugging keyboard shortcut is pressed, Blazor points the Chrome DevTools at the proxy. The proxy connects to the browser window you're seeking to debug (hence the need to enable remote debugging).
Browser source maps
Browser source maps allow the browser to map compiled files back to their original source files and are commonly used for client-side debugging. However, Blazor doesn't currently map C# directly to JavaScript/WASM. Instead, Blazor does IL interpretation within the browser, so source maps aren't relevant.
Firewall configuration
If a firewall blocks communication with the debug proxy, create a firewall exception rule that permits communication between the browser and the NodeJS
process.
Warning
Modification of a firewall configuration must be made with care to avoid creating security vulnerablities. Carefully apply security guidance, follow best security practices, and respect warnings issued by the firewall's manufacturer.
Debugging Blazor App
Permitting open communication with the NodeJS
process:
- Opens up the Node server to any connection, depending on the firewall's capabilities and configuration.
- Might be risky depending on your network.
- Is only recommended on developer machines.
If possible, only allow open communication with the NodeJS
process on trusted or private networks.
For Windows Firewall configuration guidance, see Create an Inbound Program or Service Rule. For more information, see Windows Defender Firewall with Advanced Security and related articles in the Windows Firewall documentation set.
Troubleshoot
If you're running into errors, the following tips may help:
- In the Debugger tab, open the developer tools in your browser. In the console, execute
localStorage.clear()
to remove any breakpoints. - Confirm that you've installed and trusted the ASP.NET Core HTTPS development certificate. For more information, see Enforce HTTPS in ASP.NET Core.
- Visual Studio requires the Enable JavaScript debugging for ASP.NET (Chrome, Edge and IE) option in Tools > Options > Debugging > General. This is the default setting for Visual Studio. If debugging isn't working, confirm that the option is selected.
- If your environment uses an HTTP proxy, make sure that
localhost
is included in the proxy bypass settings. This can be done by setting theNO_PROXY
environment variable in either:- The
launchSettings.json
file for the project. - At the user or system environment variables level for it to apply to all apps. When using an environment variable, restart Visual Studio for the change to take effect.
- The
- Ensure that firewalls or proxies don't block communication with the debug proxy (
NodeJS
process). For more information, see the Firewall configuration section.
Breakpoints in OnInitialized{Async}
not hit
The Blazor framework's debugging proxy takes a short time to launch, so breakpoints in the OnInitialized{Async}
lifecycle methods might not be hit. We recommend adding a delay at the start of the method body to give the debug proxy some time to launch before the breakpoint is hit. You can include the delay based on an if
compiler directive to ensure that the delay isn't present for a release build of the app.
OnInitialized:
OnInitializedAsync:
Vs Code Blazor Wasm
Visual Studio (Windows) timeout
Debug Blazor Visual Studio Code
If Visual Studio throws an exception that the debug adapter failed to launch mentioning that the timeout was reached, you can adjust the timeout with a Registry setting:
Blazer Page App
The {TIMEOUT}
placeholder in the preceding command is in milliseconds. For example, one minute is assigned as 60000
.