How to deploy Blazor WebAssembly to Heroku
Tags: dotnet, blazor, heroku
Published: 2021-03-01 18:02:02

---
title: How to deploy Blazor WebAssembly to Heroku
published: true
date: 2021-02-28 00:00:00 UTC
tags: dotnet, blazor, heroku
canonical_url: https://swimburger.net/blog/dotnet/how-to-deploy-blazor-webassembly-to-heroku
cover_image: https://swimburger.net/media/juxj42y5/blazor-heroku-social.png?anchor=center&mode=crop&width=1000&height=420&rnd=132590083879500000
---

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:

- [Azure Static Web Apps](https://swimburger.net/blog/dotnet/how-to-deploy-aspnet-blazor-webassembly-to-azure-static-web-apps)
- [GitHub Pages](https://swimburger.net/blog/dotnet/how-to-deploy-aspnet-blazor-webassembly-to-github-pages)
- [Firebase Hosting](https://swimburger.net/blog/dotnet/how-to-deploy-blazor-webassembly-to-firebase-hosting)
- [Netlify](https://swimburger.net/blog/dotnet/how-to-deploy-blazor-webassembly-to-netlify "How to deploy Blazor WebAssembly to Netlify")
- [AWS Amplify](https://swimburger.net/blog/dotnet/how-to-deploy-blazor-webassembly-to-aws-amplify "How to deploy Blazor WebAssembly to AWS Amplify")

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](https://youtu.be/8a5Pz3oZzNY) 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](https://www.youtube.com/channel/UCYcY4DDATnpJ-aNOwI4E1Iw) | [Facebook](https://www.facebook.com/SwimburgerDotNet)) or [sent a tweet](https://twitter.com/RealSwimburger) 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](https://github.com/heroku/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](https://dotnet.microsoft.com/download))
- [Heroku Account](https://www.heroku.com/)
- Heroku CLI ([download](https://devcenter.heroku.com/articles/heroku-cli#download-and-install))
- 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](https://github.com/Swimburger/BlazorWasmHeroku).**

## Create Blazor WebAssembly project

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

```powershell
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](https://localhost:5001/)):

```powershell
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:

```powershell
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:

```powershell
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:

```powershell
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** :

```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** :

```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](https://stedolan.github.io/jq/download/) if you don't have it on your machine already.

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

```powershell
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:

```powershell
heroku plugins:install heroku-cli-static
```

Run the following command to create the '_static.json_' configuration file:

```powershell
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:

```json
{
    "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:

```powershell
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:

```powershell
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:

```json
{
  "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:

```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:

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

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

```powershell
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:

- Checkout code from Git
- Install the .NET SDK
- Run the `dotnet publish` command
- Install the Heroku CLI
- Install the 'heroku-cli-static' plugin
- [Authenticate to Heroku using API token or SSH key](https://devcenter.heroku.com/articles/authentication)
- Run the `heroku static:deploy` command

Let me know what other guides you would like to see by leaving a comment ([YouTube](https://www.youtube.com/channel/UCYcY4DDATnpJ-aNOwI4E1Iw) | [Facebook](https://www.facebook.com/SwimburgerDotNet)) or sending a [tweet](https://twitter.com/RealSwimburger). Cheers!