Swimburger

How to deploy Blazor WebAssembly to Heroku

Niels Swimberghe

Niels Swimberghe - - .NET

Follow me on Twitter, buy me a coffee

Title: "How to deploy Blazor WebAssembly to Heroku". Below the title: Blazor and the Heroku logo.

With ASP.NET Blazor WebAssembly (WASM) you can create .NET web applications that run completely inside of the browser sandbox. The published output of a Blazor WASM project are static files. Now that you can run .NET web applications without server-side code, you can deploy these applications to various static site hosts such as:

I wasn't going to cover Heroku because they don't offer static site hosting. But last week, I received a comment on one of my YouTube videos asking for a tutorial on deploying Blazor WASM to Heroku. Even though there's no official static site offering by Heroku yet, Heroku does have an experimental "buildpack" for static sites.

If you have a request, leave a comment (YouTube | Facebook) or sent a tweet and I'll happily consider it.

This walkthrough will show you how to deploy Blazor WASM to Heroku using the Heroku CLI and the 'heroku-buildpack-static'. Heroku is a cloud platform—now owned by Salesforce—for building apps using their PaaS services.

This guide will walk you through these high-level steps:

  1. Create Blazor WebAssembly project
  2. Create a new Heroku application using Heroku CLI
  3. Configure Heroku application for static site hosting
  4. Deploy Blazor application using Heroku CLI

Prerequisites:

  • .NET SDK (download)
  • Heroku Account
  • Heroku CLI (download)
  • OS with support for .NET and Heroku CLI
    (this tutorial has been verified using Windows 10 & Ubuntu 18.04)

You can find the source code for this guide on GitHub.

Create Blazor WebAssembly project

Run the following commands to create a new Blazor WASM project:

mkdir BlazorWasmHeroku
cd BlazorWasmHeroku
dotnet new blazorwasm

To give your application a try, execute dotnet run and browse to the URL in the output (probably https://localhost:5001):

dotnet run
# Building...
# info: Microsoft.Hosting.Lifetime[0]
#       Now listening on: https://localhost:5001
# info: Microsoft.Hosting.Lifetime[0]
#       Now listening on: http://localhost:5000
# info: Microsoft.Hosting.Lifetime[0]
#       Application started. Press Ctrl+C to shut down.
# info: Microsoft.Hosting.Lifetime[0]
#       Hosting environment: Development
# info: Microsoft.Hosting.Lifetime[0]
#       Content root path: C:\Users\niels\source\repos\BlazorWasmHeroku
# info: Microsoft.Hosting.Lifetime[0]
#       Application is shutting down...

Optional: You can use the dotnet publish command to publish the project and verify the output:

dotnet publish
# Microsoft (R) Build Engine version 16.8.0+126527ff1 for .NET
# Copyright (C) Microsoft Corporation. All rights reserved.
# 
#   Determining projects to restore...
#   All projects are up-to-date for restore.
#   BlazorWasmHeroku -> C:\Users\niels\source\repos\BlazorWasmHeroku\bin\Debug\net5.0\BlazorWasmHeroku.dll
#   BlazorWasmHeroku (Blazor output) -> C:\Users\niels\source\repos\BlazorWasmHeroku\bin\Debug\net5.0\wwwroot  Optimizing assemblies for size, which may change the behavior of the app. Be sure to test after publishing. See: https://aka.ms/dotnet-illink
#   Compressing Blazor WebAssembly publish artifacts. This may take a while...
#   BlazorWasmHeroku -> C:\Users\niels\source\repos\BlazorWasmHeroku\bin\Debug\net5.0\publish\

In the publish directory, you will find a web.config file and a wwwroot folder. The config file helps you host your application in IIS, but you don't need that file for static site hosts. Everything you need will be inside of the wwwroot folder. The wwwroot folder contains the index.html, CSS, JS, and DLL files necessary to run the Blazor application.

Create and configure Heroku application

You need to log in before you can do anything with the Heroku CLI. Run the following command:

heroku login

The CLI will print a URL where you need to login to Heroku. If you can't use a web browser on the machine, you can also login using your username, password, and your second factor by passing in the -i argument:

heroku login -i

You can use the heroku create to create a new application, but you'll also need to capture the Application ID to specify the application in future commands.
Run the following command using PowerShell or Bash:

PowerShell:

$AppId = (heroku create --json | ConvertFrom-Json).id

By passing in the --json argument, the Heroku CLI will return the result as JSON. This JSON is converted to an object using the built-in ConvertFrom-Json cmdlet.
From the object, the id property is grabbed and stored in the $AppId variable.

Bash:

AppId=$(heroku create --json | jq -r '.id')

By passing in the --json argument, the Heroku CLI will return the result as JSON. The JSON is passed to the jq utility which queries the id property which is stored in the AppId variable.
You'll need to install the jq utility if you don't have it on your machine already.

Configure the app to use the 'heroku-buildpack-static' buildpack:

heroku buildpacks:set https://github.com/heroku/heroku-buildpack-static -a $AppId

This buildpack will wire up all the static hosting functionality for your Heroku application.

The static website will require some configuration which can be generated by the 'heroku-cli-static' plugin. Run the following commands to install the plugin into your Heroku CLI:

heroku plugins:install heroku-cli-static

Run the following command to create the 'static.json' configuration file:

heroku static:init
# ? Enter the directory of your app:                  release/wwwroot
# ? Drop `.html` extensions from urls?                Yes
# ? Path to custom error page from root directory:    index.html

The command will ask you some questions. Answer them like this:

  • Enter the directory of your app: release/wwwroot
    This is the location where you will publish the Blazor WASM application later.
  • Drop `.html` extensions from URLs? Yes
  • Path to custom error page from root directory: index.html

This command will have created the following 'static.json' file:

{
    "root": "release/wwwroot",
    "clean_urls": true,
    "error_page": "index.html"
}

Deploy Blazor WASM to the Heroku application

Run the following command to publish the Blazor WASM project:

dotnet publish -c Release -o release

The c-argument tells the CLI to build in Release configuration. The o-argument tells the CLI to put the output in the release folder.

Run the following command from the 'heroku-cli-static' plugin to deploy your Blazor app to your Heroku application:

heroku static:deploy -a $AppId

Navigate to your application using a web browser and verify your Blazor WASM application is returned and everything is working.
Almost everything that is. When you navigate to the counter page and refresh the page, you will get a 404 error.

Rewrite all requests to index.html

To fix the 404 issues, you need to tell the static Heroku app to rewrite all requests to index.html. You can do this by adding 'routes' to the 'static.json' configuration file:

{
  "root": "release/wwwroot",
  "clean_urls": true,
  "error_page": "index.html",
  "routes": {
    "/**": "index.html"
  }
}

The '/**' route will match all requests and rewrite them to 'index.html'. Here's a PowerShell and Bash snippet to make the changes to your 'static.json' file:

PowerShell:

$StaticConfig = Get-Content ./static.json | ConvertFrom-Json
$StaticConfig | Add-Member -NotePropertyName "routes" -NotePropertyValue @{"/**" = "index.html"}
Set-Content ./static.json -Value $($StaticConfig | ConvertTo-Json)

Bash:

echo $(cat static.json | jq '.routes={"/**": "index.html"}') > static.json

Run the deploy command again for the changes to take effect:

heroku static:deploy -a $AppId

When you refresh the counter page now, you will not get any 404 errors anymore.

Next Steps

Now that you have learned how to create and deploy a static web application to Heroku, you can use this knowledge to automate the deployment aspect inside a continuous deployment (CD) pipeline.
The implementation details for every CI/CD platform will be different, but  the high-level steps for a CD pipeline would be:

Let me know what other guides you would like to see by leaving a comment (YouTube | Facebook) or sending a tweet. Cheers!

Related Posts

Related Posts