HUGO
Menu
GitHub 89969 stars Mastodon

Host on Azure Static Web Apps

Host your project on Azure Static Web Apps.

Use these instructions to enable continuous deployment from a GitHub repository. The same general steps apply for other Git providers such as GitLab or Bitbucket.

Do not commit the contents of the publishDir to your repository. Hugo recreates this directory when you build your project.

Prerequisites

Please complete the following tasks before continuing:

  1. Create a Microsoft account.
  2. Create an Azure account.
  3. Log in to the Azure Portal.
  4. Create a GitHub account.
  5. Log in to your GitHub account.
  6. Create a GitHub repository for your project.
  7. Create a local Git repository for your project with a remote reference to your GitHub repository.
  8. Create a Hugo project within your local Git repository and test it with the hugo server command.
  9. Commit the changes to your local Git repository and push to your GitHub repository.

Procedure

Step 1
Create an Azure Static Web App.
  1. Go to Static Web Apps in the Azure Portal.

  2. Press the Create button.

    screen capture
  3. Under Project details, select your Subscription and choose or create a Resource Group.

    screen capture
  4. Under Static Web App details, enter a Name for your site.

    screen capture
  5. Under Hosting plan, select Free.

    screen capture
  6. Under Deployment details, select Other as the deployment source, then press the Review + create button. This allows deployment using a GitHub Actions token without auto-generating default workflow files.

    screen capture
  7. Wait for the validation to complete, then press the Create button.

    screen capture
  8. Once the deployment is complete, press the Go to resource button.

    screen capture
  9. Copy the assigned URL to your clipboard.

    screen capture
  10. In the project configuration file in the root of your local Git repository, set the baseURL to the assigned URL as shown below.

    baseURL: https://salmon-desert-04c512910.4.azurestaticapps.net/
    locale: en-US
    title: 'Hosting Test - Azure'
    
    baseURL = 'https://salmon-desert-04c512910.4.azurestaticapps.net/'
    locale = 'en-US'
    title = 'Hosting Test - Azure'
    
    {
       "baseURL": "https://salmon-desert-04c512910.4.azurestaticapps.net/",
       "locale": "en-US",
       "title": "Hosting Test - Azure"
    }
    
  11. Click the Manage deployment token link at the top of the page, and copy the deployment token to your clipboard.

    screen capture
Step 2
Add the deployment token to GitHub Secrets.
  1. Go to your GitHub repository.
  2. Navigate to Settings > Secrets and variables > Actions.
  3. Click the New repository secret button.
  4. Enter AZURE_STATIC_WEB_APPS_API_TOKEN for the Name.
  5. Paste the deployment token into the Secret field.
  6. Press the Add secret button.
Step 3
Create a hugo.yaml file in the .github/workflows directory, adjusting the tool versions and time zone as needed.
.github/workflows/hugo.yaml
name: Build and deploy
env:
  # Define tool versions
  DART_SASS_VERSION: 1.104.0
  GO_VERSION: 1.27.0
  HUGO_VERSION: 0.166.0
  NODE_VERSION: 24.20.0

  # Set the build time zone
  TZ: Europe/Oslo
on:
  push:
    branches:
      - main
  workflow_dispatch:
permissions:
  contents: read
concurrency:
  group: deployment
  cancel-in-progress: false
defaults:
  run:
    shell: bash
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v7
        with:
          submodules: recursive
          fetch-depth: 0
          lfs: false

      - name: Create a local tools directory
        run: |
          mkdir -p "${HOME}/.local"

      - name: Install Go
        if: hashFiles('go.mod') != ''
        uses: actions/setup-go@v7
        with:
          go-version: ${{ env.GO_VERSION }}
          cache: false

      - name: Install Node.js
        if: hashFiles('package-lock.json') != ''
        uses: actions/setup-node@v7
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Install Dart Sass
        run: |
          echo "Installing Dart Sass ${DART_SASS_VERSION}..."
          curl -sfL --output-dir "${{ runner.temp }}" -O "https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz"
          tar -C "${HOME}/.local" -xf "${{ runner.temp }}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz"
          echo "${HOME}/.local/dart-sass" >> "${GITHUB_PATH}"

      - name: Install Hugo
        run: |
          echo "Installing Hugo ${HUGO_VERSION}..."
          curl -sfL --output-dir "${{ runner.temp }}" -O "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-amd64.tar.gz"
          mkdir "${HOME}/.local/hugo"
          tar -C "${HOME}/.local/hugo" -xf "${{ runner.temp }}/hugo_${HUGO_VERSION}_linux-amd64.tar.gz"
          echo "${HOME}/.local/hugo" >> "${GITHUB_PATH}"

      - name: Log tool versions
        run: |
          echo "Logging tool versions..."
          command -v sass &> /dev/null && echo "Dart Sass: $(sass --version)" || echo "Dart Sass: not installed"
          command -v go &> /dev/null && echo "Go: $(go version)" || echo "Go: not installed"
          command -v hugo &> /dev/null && echo "Hugo: $(hugo version)" || echo "Hugo: not installed"
          command -v node &> /dev/null && echo "Node.js: $(node --version)" || echo "Node.js: not installed"

      - name: Configure Git
        run: |
          echo "Configuring Git..."
          git config --global core.quotepath false

      - name: Fetch full Git history
        run: |
          if [[ $(git rev-parse --is-shallow-repository) == true ]]; then
            echo "Fetching full Git history..."
            git fetch --unshallow
          fi

      - name: Initialize Git submodules
        run: |
          if [[ -f .gitmodules ]]; then
            echo "Initializing Git submodules..."
            git submodule update --init --recursive
          fi

      - name: Install Node.js dependencies
        run: |
          if [[ -f package-lock.json ]]; then
            echo "Installing Node.js dependencies..."
            npm ci
          fi

      - name: Cache restore
        id: cache-restore
        uses: actions/cache/restore@v6
        with:
          path: ${{ runner.temp }}/.cache/hugo
          key: hugo-${{ github.run_id }}
          restore-keys: hugo-

      - name: Build
        run: |
          echo "Building the project..."
          hugo build \
            --gc \
            --minify \
            --cacheDir "${{ runner.temp }}/.cache/hugo"

      - name: Cache save
        uses: actions/cache/save@v6
        with:
          path: ${{ runner.temp }}/.cache/hugo
          key: ${{ steps.cache-restore.outputs.cache-primary-key }}

      - name: Upload build artifact
        uses: actions/upload-artifact@v7
        with:
          name: build-artifact
          path: public
          retention-days: 1
  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Download build artifact
        uses: actions/download-artifact@v8
        with:
          name: build-artifact
          path: public

      - name: Create Azure Static Web Apps config
        run: |
          cat << 'EOF' > staticwebapp.config.json
          {
            "responseOverrides": {
              "404": {
                "rewrite": "/404.html",
                "statusCode": 404
              }
            }
          }
          EOF

      - name: Setup Node.js
        uses: actions/setup-node@v7
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Install SWA CLI
        run: npm install -g @azure/static-web-apps-cli --no-fund --no-audit --quiet

      - name: Deploy
        env:
          SWA_CLI_DEPLOYMENT_TOKEN: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }}
        run: swa deploy ./public --env production --api-location "" --swa-config-location ./
Step 4
In the project configuration file in the root of your local Git repository, set the location of the image cache to the cacheDir as shown below.
caches:
  images:
    dir: :cacheDir/images
[caches]
  [caches.images]
    dir = ':cacheDir/images'
{
   "caches": {
      "images": {
         "dir": ":cacheDir/images"
      }
   }
}

See configure file caches for more information.

Step 5
Commit the changes to your local Git repository and push to your GitHub repository.
Step 6
From GitHub’s main menu, choose Actions. You will see something like this: screen capture
Step 7
When GitHub has finished building and deploying your site, the color of the status indicator will change to green. screen capture

In the future, whenever you push a change from your local Git repository, GitHub will rebuild and deploy your site.

For more information on hosting and managing your site with Azure Static Web Apps, consult the official documentation: