June 10, 2026

Deploying a Next.js Portfolio to GitHub Pages with Actions

This site is a static export — no server, no API routes at request time. That keeps hosting on GitHub Pages simple, but it means a few defaults need to change.

The config changes

Three settings in next.config make the build static-export friendly:

const nextConfig = {
  output: "export",
  trailingSlash: true,
  images: { unoptimized: true },
};

output: "export" produces a plain out/ directory of HTML, CSS, and JS. trailingSlash: true makes nested routes resolve as folders with their own index.html, which is how GitHub Pages expects static sites to be structured. images.unoptimized turns off next/image's server-side optimization, since there's no server to do it.

If the site lives at username.github.io/repo-name rather than a custom domain, basePath and assetPrefix also need to point at /repo-name, or every internal link and asset will 404.

The workflow

The GitHub Actions side is mostly boilerplate: checkout, install, build, then hand the out/ directory to GitHub's Pages actions.

- uses: actions/checkout@v4
- uses: actions/setup-node@v4
  with:
    node-version: 20
    cache: npm
- run: npm ci
- run: npm run build
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v3
  with:
    path: ./out
- uses: actions/deploy-pages@v4

What tripped me up

The first build failed silently on image paths because I'd forgotten the basePath change — everything worked locally since npm run dev doesn't apply it. Running npx serve out locally after a production build catches this kind of issue before it reaches Pages.