---
title: "How to deploy Blazor WebAssembly to Heroku"
excerpt: "Heroku doesn't officially offer a static hosting service but does have an experimental 'buildpack' which gives you static hosting capabilities you can use to deploy and host Blazor WebAssembly."
publishDate: "2021-02-28T00:00:00"
createDate: "2021-02-26T00:19:39.667"
updateDate: "2021-04-02T23:33:36.38"
category: "dotnet"
categoryName: ".NET"
tags: [".NET","ASP.NET","Blazor","Blazor WASM","Blazor WebAssembly","Heroku"]
permalink: "/blog/dotnet/how-to-deploy-blazor-webassembly-to-heroku"
canonical: "/blog/dotnet/how-to-deploy-blazor-webassembly-to-heroku"
image: {"src":"/media/lgcc0fba/blazor-heroku-long.png","focalPoint":{"left":0.5,"top":0.5},"crops":[{"alias":"Banner","width":1120,"height":400,"coordinates":null}]}
imageAlt: "Title: \"How to deploy Blazor WebAssembly to Heroku\". Below the title: Blazor and the Heroku logo."
imageBackgroundColor: "#fff"
thumbnailImage: {"src":"/media/bx5dy2pl/blazor-heroku-square.png","focalPoint":{"left":0.5,"top":0.5},"crops":[{"alias":"thumbnail","width":250,"height":250,"coordinates":null}]}
thumbnailImageAlt: "Heroku and Blazor logo"
metaTitle: "How to deploy Blazor WebAssembly to Heroku"
metaDescription: "Heroku doesn't officially offer a static hosting service but does have an experimental 'buildpack' which gives you static hosting capabilities you can use to deploy and host Blazor WebAssembly."
ogTitle: "How to deploy Blazor WebAssembly to Heroku"
ogDescription: "Heroku doesn't officially offer a static hosting service but does have an experimental 'buildpack' which gives you static hosting capabilities you can use to deploy and host Blazor WebAssembly."
ogImage: {"src":"/media/juxj42y5/blazor-heroku-social.png","focalPoint":{"left":0.5,"top":0.5},"crops":[{"alias":"OpenGraph","width":1200,"height":630,"coordinates":null}]}
ogImageAlt: "Title: \"How to deploy Blazor WebAssembly to Heroku\". Below the title: Blazor and the Heroku logo."
relatedPostKeys: ["3fa142faee1a488c91f507627e8059bb","0d375026e40743fdadc9c3b841802a6a","1220545262ab42c291420e12ca2e6025","b01d783c18284f05b29774abcd096471","866430e9df2e4fe9a7805fbfa47eb9a4"]
noIndex: false
noFollow: false
sitemapExclude: false
source: {"nodeId":1455,"contentKey":"712bacbb348946db96f735a4f3171340","sortOrder":86}
---


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 <strong>static files</strong>. Now that you can run .NET web applications without server-side code, you can deploy these applications to various <strong>static site hosts </strong>such as:





-   [Azure Static Web Apps using GitHub](https://swimburger.net/blog/dotnet/how-to-deploy-aspnet-blazor-webassembly-to-azure-static-web-apps)
-   [Azure Static Web Apps using Azure DevOps (by Dave Brock)](https://daveabrock.com/2021/04/01/static-web-apps-azure-pipelines)
-   <a href="/blog/dotnet/how-to-deploy-blazor-webassembly-to-aws-amplify" title="How to deploy Blazor WebAssembly to AWS Amplify">AWS Amplify</a>
-   <a href="/blog/dotnet/how-to-deploy-blazor-webassembly-to-netlify" title="How to deploy Blazor WebAssembly to Netlify">Netlify</a>
-   <a href="/blog/dotnet/how-to-deploy-blazor-webassembly-to-cloudflare-pages" title="How to deploy Blazor WebAssembly to Cloudflare Pages">Cloudflare Pages</a>
-   <a href="/blog/dotnet/how-to-deploy-blazor-webassembly-to-digitalocean-app-platform" title="How to deploy Blazor WebAssembly to DigitalOcean App Platform">DigitalOcean App Platform</a>
-   [GitHub Pages](https://swimburger.net/blog/dotnet/how-to-deploy-aspnet-blazor-webassembly-to-github-pages)<a href="/blog/dotnet/how-to-deploy-blazor-webassembly-to-aws-amplify" title="How to deploy Blazor WebAssembly to AWS Amplify"></a>
-   [Firebase Hosting](https://swimburger.net/blog/dotnet/how-to-deploy-blazor-webassembly-to-firebase-hosting)


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.

<p class="panel panel--info">If you have a request, leave a comment (<a href="https://www.youtube.com/channel/UCYcY4DDATnpJ-aNOwI4E1Iw">YouTube</a> | <a href="https://www.facebook.com/SwimburgerDotNet">Facebook</a>) or <a href="https://twitter.com/RealSwimburger">sent a tweet</a> and I'll happily consider it.</p>




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 (<a href="https://dotnet.microsoft.com/download">download</a>)
- <a href="https://www.heroku.com/">Heroku Account</a>
- Heroku CLI (<a href="https://devcenter.heroku.com/articles/heroku-cli#download-and-install">download</a>)
- OS with support for .NET and Heroku CLI <br>(this tutorial has been verified using Windows 10 &amp; Ubuntu 18.04)




<p class="panel panel--info"><strong>You can find the <a href="https://github.com/Swimburger/BlazorWasmHeroku">source code for this guide on GitHub</a>.</strong></p>



## Create Blazor WebAssembly project {#create-aspnet-core-blazor-webassembly-project no-anchor}

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

<pre style="color:#000000;background:#ffffff;">mkdir <span style="color:#2a00ff; ">BlazorWasmHeroku</span>&#10;cd <span style="color:#2a00ff; ">BlazorWasmHeroku</span>&#10;dotnet <span style="color:#2a00ff; ">new</span> <span style="color:#2a00ff; ">blazorwasm</span></pre>




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




<pre style="color:#000000;background:#ffffff;">dotnet <span style="color:#2a00ff; ">run</span>&#10;<span style="color:#3f7f59; "># Building...</span>&#10;<span style="color:#3f7f59; "># info: Microsoft.Hosting.Lifetime[0]</span>&#10;<span style="color:#3f7f59; ">#       Now listening on: </span><span style="color:#3f3fbf; ">https://localhost:5001</span>&#10;<span style="color:#3f7f59; "># info: Microsoft.Hosting.Lifetime[0]</span>&#10;<span style="color:#3f7f59; ">#       Now listening on: </span><span style="color:#3f3fbf; ">http://localhost:5000</span>&#10;<span style="color:#3f7f59; "># info: Microsoft.Hosting.Lifetime[0]</span>&#10;<span style="color:#3f7f59; ">#       Application started. Press Ctrl+C to shut down.</span>&#10;<span style="color:#3f7f59; "># info: Microsoft.Hosting.Lifetime[0]</span>&#10;<span style="color:#3f7f59; ">#       Hosting environment: Development</span>&#10;<span style="color:#3f7f59; "># info: Microsoft.Hosting.Lifetime[0]</span>&#10;<span style="color:#3f7f59; ">#       Content root path: C:\Users\niels\source\repos\BlazorWasmHeroku</span>&#10;<span style="color:#3f7f59; "># info: Microsoft.Hosting.Lifetime[0]</span>&#10;<span style="color:#3f7f59; ">#       Application is shutting down...</span>&#10;</pre>

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

<pre style="color:#000000;background:#ffffff;">dotnet <span style="color:#2a00ff; ">publish</span>&#10;<span style="color:#3f7f59; "># Microsoft (R) Build Engine version 16.8.0+126527ff1 for .NET</span>&#10;<span style="color:#3f7f59; "># Copyright (C) Microsoft Corporation. All rights reserved.</span>&#10;<span style="color:#3f7f59; "># </span>&#10;<span style="color:#3f7f59; ">#   Determining projects to restore...</span>&#10;<span style="color:#3f7f59; ">#   All projects are up-to-date for restore.</span>&#10;<span style="color:#3f7f59; ">#   BlazorWasmHeroku -&gt; C:\Users\niels\source\repos\BlazorWasmHeroku\bin\Debug\net5.0\BlazorWasmHeroku.dll</span>&#10;<span style="color:#3f7f59; ">#   BlazorWasmHeroku (Blazor output) -&gt; 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: </span><span style="color:#3f3fbf; ">https://aka.ms/dotnet-illink</span>&#10;<span style="color:#3f7f59; ">#   Compressing Blazor WebAssembly publish artifacts. This may take a while...</span>&#10;<span style="color:#3f7f59; ">#   BlazorWasmHeroku -&gt; C:\Users\niels\source\repos\BlazorWasmHeroku\bin\Debug\net5.0\publish\</span>&#10;</pre>




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 {#create-aspnet-core-blazor-webassembly-project-2 no-anchor}

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

<pre style="color:#000000;background:#ffffff;">heroku <span style="color:#2a00ff; ">login</span>&#10;</pre>

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:

<pre style="color:#000000;background:#ffffff;">heroku <span style="color:#2a00ff; ">login</span> -i&#10;</pre>

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.<br>Run the following command using PowerShell or Bash:


**PowerShell**:




<pre style="color:#000000;background:#ffffff;">$AppId = (heroku <span style="color:#2a00ff; ">create</span> <span style="color:#2a00ff; ">--json</span> <span style="color:#7f0055; font-weight:bold; ">|</span> ConvertFrom-Json).id&#10;</pre>

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.<br>From the object, the `id` property is grabbed and stored in the `$AppId` variable.


**Bash**:




<pre style="color:#000000;background:#ffffff;">AppId=$(heroku create --json | jq -r <span style="color:#2a00ff; ">'.id'</span>)&#10;</pre>

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.<br>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:

<pre style="color:#000000;background:#ffffff;">heroku buildpacks:<span style="color:#7f0055; font-weight:bold; ">set</span> https:<span style="color:#3f3fbf; ">/</span><span style="color:#3f3fbf; ">/github.com/heroku/heroku-buildpack-static</span> -a $AppId&#10;</pre>

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:

<pre style="color:#000000;background:#ffffff;">heroku plugins:install heroku-cli-static&#10;</pre>




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




<pre style="color:#000000;background:#ffffff;">heroku <span style="color:#2a00ff; ">static:init</span>&#10;<span style="color:#3f7f59; "># ? Enter the directory of your app:                  release/wwwroot</span>&#10;<span style="color:#3f7f59; "># ? Drop `.html` extensions from urls?                Yes</span>&#10;<span style="color:#3f7f59; "># ? Path to custom error page from root directory:    index.html</span>&#10;</pre>

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

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




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




<pre style="color:#000000;background:#ffffff;">{&#10;    <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">root</span><span style="color:#2a00ff; ">"</span>: <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">release/wwwroot</span><span style="color:#2a00ff; ">"</span>,&#10;    <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">clean_urls</span><span style="color:#2a00ff; ">"</span>: <span style="color:#7f0055; font-weight:bold; ">true</span>,&#10;    <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">error_page</span><span style="color:#2a00ff; ">"</span>: <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">index.html</span><span style="color:#2a00ff; ">"</span>&#10;}&#10;</pre>



## Deploy Blazor WASM to the Heroku application {#create-aspnet-core-blazor-webassembly-project-3 no-anchor}

Run the following command to publish the Blazor WASM project:

<pre style="color:#000000;background:#ffffff;">dotnet <span style="color:#2a00ff; ">publish</span> -c <span style="color:#2a00ff; ">Release</span> -o <span style="color:#2a00ff; ">release</span>&#10;</pre>




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:

<pre style="color:#000000;background:#ffffff;">heroku <span style="color:#2a00ff; ">static:deploy</span> -a $AppId&#10;</pre>




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




## Rewrite all requests to index.html {#rewrite-all-requests-to-indexhtml no-anchor}




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:




<pre style="color:#000000;background:#ffffff;">{&#10;  <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">root</span><span style="color:#2a00ff; ">"</span>: <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">release/wwwroot</span><span style="color:#2a00ff; ">"</span>,&#10;  <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">clean_urls</span><span style="color:#2a00ff; ">"</span>: <span style="color:#7f0055; font-weight:bold; ">true</span>,&#10;  <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">error_page</span><span style="color:#2a00ff; ">"</span>: <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">index.html</span><span style="color:#2a00ff; ">"</span>,&#10;  <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">routes</span><span style="color:#2a00ff; ">"</span>: {&#10;    <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">/**</span><span style="color:#2a00ff; ">"</span>: <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">index.html</span><span style="color:#2a00ff; ">"</span>&#10;  }&#10;}&#10;</pre>




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:

<pre style="color:#000000;background:#ffffff;">$StaticConfig = Get-Content <span style="color:#2a00ff; ">./static.json</span> <span style="color:#7f0055; font-weight:bold; ">|</span> ConvertFrom-Json&#10;$StaticConfig <span style="color:#7f0055; font-weight:bold; ">|</span> Add-Member -NotePropertyName <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">routes</span><span style="color:#2a00ff; ">"</span> -NotePropertyValue @{<span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">/**</span><span style="color:#2a00ff; ">"</span> = <span style="color:#2a00ff; ">"</span><span style="color:#2a00ff; ">index.html</span><span style="color:#2a00ff; ">"</span>}&#10;Set-Content <span style="color:#2a00ff; ">./static.json</span> -Value $($StaticConfig <span style="color:#7f0055; font-weight:bold; ">|</span> ConvertTo-Json)&#10;</pre>

Bash:

<pre style="color:#000000;background:#ffffff;"><span style="color:#7f0055; font-weight:bold; ">echo</span> $(cat static<span style="color:#7f0055; font-weight:bold; ">.</span>json | jq <span style="color:#2a00ff; ">'.routes={"/**": "index.html"}'</span>) &gt; static<span style="color:#7f0055; font-weight:bold; ">.</span>json&#10;</pre>

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

<pre style="color:#000000;background:#ffffff;">heroku <span style="color:#2a00ff; ">static:deploy</span> -a $AppId&#10;</pre>

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

## Next Steps {#rewrite-all-requests-to-indexhtml-2 no-anchor}

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.<br>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[](https://devcenter.heroku.com/articles/authentication)
-   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!
