Publishing a Blazor WebAssembly application to GitHub pages

 
 
  • Gérald Barré

Blazor WebAssembly is now officially released and is ready for production use. Blazor WebAssembly runs your client-side C# code directly in the browser, using WebAssembly. This means your application doesn't need a server and can be published as a static website.

There are multiple possibilities to host a static web site such as Azure Storage, AWS S3, Google Cloud Storage, etc. GitHub pages is a free alternative as long as you do not run a high-traffic website (usage limits). Note that you can use Cloudflare free to reduce the usage of the GitHub quota.

#Creating the GitHub repository

First, you need to create a repository on GitHub. The name of the repository will set the URL of the website generated by GitHub. If you plan to use a custom domain name, the repository name is not important as you'll be able to map any repository to a custom URL. If you don't have a custom domain name, GitHub will generate one for your project as the following:

  • Repository name: <username>.github.io → URL: https://<username>.github.io
  • Repository name: demo → URL: https://<username>.github.io/demo

So you can now create your GitHub repository accordingly to your needs.

#Creating the Blazor application

  1. Clone the repository to your machine. You'll find the clone URL on your repository page:

    Shell
    git clone https://github.com/<username>/<projectname>.git
    cd <projectname>
  2. Create a new Blazor WebAssembly application:

    Shell
    dotnet new blazorwasm --name myapp --output .
  3. You can now test the application:

    Shell
    dotnet run

If you deploy the website to a subfolder such as https://meziantou.github.io/DemoBlazorGitHubPages, you need to edit the file wwwroot/index.html to set the base URL:

HTML
<base href="/DemoBlazorGitHubPages/" />

You can automate this step using a .NET tool:

Shell
dotnet tool update --global Meziantou.Framework.Html.Tool
meziantou.html replace-value --file index.html        --xpath "//base/@href" --new-value "/DemoBlazorGitHubPages"
meziantou.html replace-value --file-pattern **/*.html --xpath "//base/@href" --new-value "/DemoBlazorGitHubPages"

#Publishing the application using GitHub Actions

To publish the application, you need to publish the artifacts to the branch gh-pages or master. GitHub Actions provides a way to automate the deployment of the website when you push new changes.

First, you need to generate a token to commit the website to the branch. Go to https://github.com/settings/tokens and create a token with the scope repo

Then, you need to create a new secret so the action can use it. Go to https://github.com/<username>/<projectname>/settings/secrets/new and add a new secret named PUBLISH_TOKEN with the previously generated token:

Then, add a new file named .github/workflows/ci.yml with the following content:

YAML
name: 'Publish application'
on: push

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
        # Checkout the code
        - uses: actions/checkout@v2

        # Install .NET Core SDK
        - name: Setup .NET Core
          uses: actions/setup-dotnet@v2
          with:
            dotnet-version: 3.1.x

        # Run tests
        - name: Test
          run: dotnet test

        # Generate the website
        - name: Publish
          run: dotnet publish myapp.csproj --configuration Release

        # Publish the website
        - name: GitHub Pages action
          if: ${{ github.ref == 'refs/heads/master' }} # Publish only when the push is on master
          uses: peaceiris/actions-gh-pages@v3.6.1
          with:
            github_token: ${{ secrets.PUBLISH_TOKEN }}
            publish_branch: gh-pages
            publish_dir: bin/Release/netstandard2.1/publish/wwwroot
            allow_empty_commit: false
            keep_files: false
            force_orphan: true
            # TODO uncomment the following line if you have a custom domain name
            # cname: demo.meziantou.net

Then, push your changes to GitHub

Shell
git add .
git commit -m "Initial commit"
git push

You can now check the status of the build pipeline at https://github.com/<username>/<projectname>/actions

Finally, you must enable GitHub pages in the settings of the project by selecting the branch that contains your static files:

You should now see a new tab named 1 environment in the repository's home page:

If everything's ok, you should click on the "View deployment" button and you should see your application:

If you have an error while loading the application, check if the value of <base href="..."> in wwwroot/index.html matches your actual base URL.

#Handling 404 errors

The website is accessible but only if you query the home page. If you try to access a page such as /fetchdata, you'll get a 404 error.

This is the expected behavior as there is no HTML page with this name in the repository, so GitHub cannot serve the page and return the 404 error page. Instead of displaying the error page, you may want to serve the default file index.html and let Blazor handle the routing. An easy way to do that is by duplicating the file. You can do it manually or you can do it in the CI.

YAML
        # Generate the website
        - name: Publish
          run: |
            cp wwwroot/index.html wwwroot/404.html
            dotnet publish myapp.csproj --configuration Release

Once the application is published, you should be able to navigate to any page of the app and press F5 to refresh the page.

#Conclusion

It's simple to deploy your Blazor WebAssembly application for free using GitHub pages. With GitHub Actions every push to the main branch will publish the new version of the application so your changes are available in a few minutes to all your users!

I've currently published 2 Blazor WebAssembly projects on GitHub pages. You can check their workflows if you need more details:

Do you have a question or a suggestion about this post? Contact me!

Follow me:
Enjoy this blog?Buy Me A Coffee💖 Sponsor on GitHub