NNicheStackTutorials
← All tutorials
Hugo

Hugo Assets Pipeline on GitHub Pages (Actions + gh-pages)

Deploy fingerprinted assets, submodules, and custom domains with GitHub Actions. Fix MIME and path errors.

·12 min read·Hugo
Hugo Assets Pipeline on GitHub Pages (Actions + gh-pages) cover

Tested on: Hugo 0.139.4-extended, GitHub Actions, user site username.github.io/repo/ Problem: CSS/JS 404, wrong MIME type, baseURL broke asset paths.

baseURL for project pages

Repo: github.com/user/myblog → served at https://user.github.io/myblog/

hugo.toml:

baseURL = "https://user.github.io/myblog/"
canonifyURLs = true
relativeURLs = false

Never use relativeURLs = true with fingerprinted assets — hashes break on nested pages.

GitHub Actions workflow

.github/workflows/hugo.yml:

name: Deploy Hugo
on:
  push:
    branches: [main]
permissions:
  contents: read
  pages: write
  id-token: write
concurrency:
  group: pages
  cancel-in-progress: true
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: recursive
          fetch-depth: 0
      - uses: actions/configure-pages@v5
      - uses: peaceiris/actions-hugo@v3
        with:
          hugo-version: '0.139.4'
          extended: true
      - run: hugo --gc --minify
      - uses: actions/upload-pages-artifact@v3
        with:
          path: public
  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - id: deployment
        uses: actions/deploy-pages@v4

Enable Pages: Settings → Pages → Source: GitHub Actions.

Fingerprinted assets

layouts/partials/head.html:

{{ $css := resources.Match "css/**/*.css" | resources.Concat "bundle.css" | minify | fingerprint }}
<link rel="stylesheet" href="{{ $css.RelPermalink }}" crossorigin="anonymous">

Output: /myblog/assets/css/bundle.abc123.css — works with project baseURL.

Error: assets 404

GET https://user.github.io/assets/css/bundle.css 404

Missing /myblog/ prefix — baseURL was https://user.github.io/ instead of project path.

Error: text/plain MIME

Refused to apply style because MIME type is 'text/plain'

Usually means 404 HTML returned for CSS URL. Fix path, not MIME config.

Custom domain on project repo

baseURL = "https://www.myblog.com/"

Add static/CNAME:

www.myblog.com

DNS: CNAME wwwuser.github.io.

Verify

hugo --minify
grep -o 'href="[^"]*css[^"]*"' public/index.html
# all URLs should start with /myblog/ or full domain

npx http-server public -p 8080
# test nested page assets

After deploy:

curl -I https://user.github.io/myblog/assets/css/bundle.*.css
# HTTP/2 200, content-type: text/css

Submodule gotcha

submodules: recursive

Without it, theme missing → 12KB unstyled HTML.

Result

812-post site deploys in 48s. Asset cache hit rate 99% on repeat visitors via fingerprint + long cache.

Tags: HugoGitHub PagesGitHub ActionsAssets