Sarıkaya Dev Logo

Build Progressive Web Apps with .NET 8 Blazor WebAssembly on Azure Static Web Apps

Mahmut Sarıkaya 4 min read 14 Views 0
Build Progressive Web Apps with .NET 8 Blazor WebAssembly on Azure Static Web Apps

Why PWAs Matter for Modern .NET Developers

Imagine a user opening a web application on a flaky 3G connection, only to see a blank screen while the server struggles to respond. A progressive web app (PWA) eliminates that frustration by caching assets, serving content offline, and delivering a native‑like experience directly from the browser. According to a 2023 Statista report, over 70% of mobile users prefer apps that work offline, making PWA support a competitive advantage for any .NET Core portfolio.

Prerequisites and System Requirements

Before diving in, ensure you have the following on your development machine: Windows 10/11 or macOS 12+, .NET 8 SDK (downloadable from Microsoft.com), Azure CLI version 2.45+, and a GitHub account for CI/CD integration. The Azure Static Web Apps free tier provides up to 100 GB bandwidth per month, which is more than enough for a proof‑of‑concept PWA.

Creating a Blazor WebAssembly Project with .NET 8

Open a terminal and run the standard template command. The --framework net8.0 switch guarantees you are using the latest runtime features, such as ahead‑of‑time (AOT) compilation for faster startup.

dotnet new blazorwasm -o MyPwa --framework net8.0

Navigate into the folder and launch the app locally to verify the default SPA works: dotnet run. You should see the familiar counter page at https://localhost:5001.

Enabling PWA Features in the Project

Blazor WebAssembly includes a built‑in PWA template, but with .NET 8 you can add the capabilities manually for full control. First, create a manifest.json file in the wwwroot folder:

{"name": "My Blazor PWA", "short_name": "MyPWA", "start_url": "/", "display": "standalone", "background_color": "#ffffff", "theme_color": "#0d6efd", "icons": [{"src": "icon-192.png", "sizes": "192x192", "type": "image/png"}, {"src": "icon-512.png", "sizes": "512x512", "type": "image/png"}]}

Reference the manifest in index.html and add a link to the service‑worker file:

<link rel="manifest" href="manifest.json">
<script src="service-worker-register.js" defer></script>

Next, create service-worker-register.js that registers the default Blazor service worker generated by the SDK:

if ('serviceWorker' in navigator) {
  window.addEventListener('load', function () {
    navigator.serviceWorker.register('service-worker.published.js');
  });
}

The SDK already ships service-worker.published.js with caching rules for static assets and DLLs. No further configuration is required for a basic offline experience.

Configuring Azure Static Web Apps for Deployment

Azure Static Web Apps automatically detects a Blazor WebAssembly output folder and configures the appropriate routes. Create a new static web app using the Azure CLI, pointing to the wwwroot folder produced after a release build:

az staticwebapp create \
  --name MyPwaApp \
  --resource-group MyResourceGroup \
  --location WestEurope \
  --source . \
  --branch main \
  --app-location "/" \
  --output-location "wwwroot" \
  --sku Free

The command provisions a GitHub Actions workflow that builds the project with dotnet publish -c Release -o wwwroot and pushes the output to Azure on every push to main. The workflow also enables the api folder for optional serverless functions, should you need backend validation.

Testing Offline Capability Locally

Run the app with dotnet run, open Chrome DevTools, and toggle the “Offline” switch under the Network tab. Refresh the page – the UI should reload instantly from the service worker cache, and the counter continues to work because the UI logic runs entirely in the browser. Use Lighthouse (available in DevTools) to audit PWA compliance; a score above 90 indicates that manifest, service worker, and HTTPS are correctly configured.

Performance Tips and Real‑World Numbers

Enabling AOT compilation with dotnet publish -c Release -p:RunAOTCompilation=true reduces the initial download size from ~2.3 MB to ~1.8 MB and cuts startup time by roughly 30% on a typical 4G connection. Combine this with HTTP/2 push headers in the staticwebapp.config.json file to pre‑load critical assets:

{"routes": [], "navigationFallback": {"rewrite": "/index.html"}, "responseOverrides": {}, "globalHeaders": {"cache-control": "max-age=31536000"}}

In production, Microsoft’s own Blazor PWA sample reports a 45% reduction in Time‑to‑First‑Byte (TTFB) after adding these headers and enabling Azure CDN. Monitoring with Azure Application Insights can further pinpoint bottlenecks.

Conclusion

Building a progressive web app with .NET 8 Blazor WebAssembly and Azure Static Web Apps is a straightforward path to delivering fast, offline‑ready experiences without leaving the .NET ecosystem. By adding a manifest, registering the built‑in service worker, and deploying through Azure’s serverless pipeline, developers gain native‑like performance, automatic scaling, and a CI/CD workflow that fits directly into existing GitHub processes. The result is a modern PWA that leverages the full power of C# while meeting user expectations for reliability and speed.

Sources

Microsoft Docs – .NET 8 Blazor WebAssembly, Azure Static Web Apps documentation, PWA Builder.

Author: Mahmut Sarıkaya — sarikayadev.com

Tags: #dotnet 8 #blazor webassembly #progressive web app #pwa #azure static web apps
Share:
M

Written by

Mahmut Sarıkaya

Software Developer

Comments

No comments yet. Be the first to share your thoughts!

Leave a Comment

1 + 7 =