Sitemap

Auto-Deploying Your Next.js App to GitHub Pages

A friendly guide based on deploying SimplyBudget

--

You’ve built a Next.js app and want to automatically deploy to GitHub Pages every time you push to your main or master branch (or some other branch). No manual builds or uploads, no fussing about. Here’s how to do it.

The whole setup comes down to three things: telling Next.js to export a static site, writing a GitHub Actions workflow that does the building and deploying for you, and flipping a switch in your repo settings. Let’s go!

Step 1: Configure Next.js for Static Export

GitHub Pages serves static files, so you need to tell Next.js to produce a folder of HTML, CSS, and JavaScript instead of a server-rendered app. Locate your nextConfig (mine was in next.config.mjs) and add the following:

const nextConfig = {
output: 'export',
basePath: '/your-repo-name',
assetPrefix: '/your-repo-name/',
images: { unoptimized: true },
};
export default nextConfig;

The basePath setting is the part people most commonly get wrong. GitHub Pages doesn’t serve your app from the root of a domain: it serves it from a path like /your-repo-name. Without basePath, your assets will 404. Make sure it matches your repository name exactly. My repo’s name is “simplybudget”, so the basePath and and assetPrefix in my project are both set to “/simplybudget”.

Since this is a frontend-only app and I didn’t use the Next.js Image component, I’ve set image optimization off: “images: { unoptimized: true }”.

Step 2: Create the GitHub Actions Workflow

Here comes the automation! Are you ready!?

Get coderSloth’s stories in your inbox

Join Medium for free to get updates from this writer.

Create a file at .github/workflows/deploy.yml in your project’s root. This file tells GitHub what to do every time you push to main/master (or whichever branch you wish to deploy from).

name: Deploy to GitHub Pages

on:
push:
branches: main # update to match your target branch/es
paths-ignore:
- "**/README.md"

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: false

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5 # check GitHub for latest version
- uses: actions/setup-node@v4 # check GitHub for latest version
with:
node-version: '25.x' # match your project or choose the latest stable release
cache: npm
- run: npm ci
- run: npm test -- --watchAll=false --passWithNoTests

build-and-deploy:
needs: test
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v5 # check GitHub for latest version
- uses: actions/setup-node@v4 # check GitHub for latest version
with:
node-version: '25.x' # match your project or choose the latest stable release
cache: npm
- run: npm ci
- run: npm run build
- uses: actions/upload-pages-artifact@v3 # check GitHub for latest version
with:
path: ./out
- id: deployment
uses: actions/deploy-pages@v4 # check GitHub for latest version

What’s happening here?
The workflow has two jobs that run in sequence:

  • test: runs your Jest suite first. If any tests fail, the project will not deploy. This prevents you from shipping broken code.
  • build-and-deploy: installs dependencies, runs next build (which produces the out/ folder thanks to “output: ‘export’”), uploads that folder, and deploys it to GitHub Pages.

The “needs: test” line under “build-and-deploy” is what connects the two jobs. It ensures the deploy job only runs if the test job succeeds.

There’s no need to test and rebuild the app if README.md is updated, so “paths-ignore” is added to prevent that from happening. If you want to prevent deployment when any .md file is updated, modify the entry from “**/README.md” to “**.md”. You can add as many items as you need. Conversely, you can also trigger a deployment when certain files are updated using the “paths” entry.

You can find more information on the Workflow syntax in GitHub Docs.

Step 3: Enable GitHub Pages in Your Repo

Head to your repository on GitHub, then go to Settings → Pages. Under Source, select GitHub Actions (not the “Deploy from a branch” option). Save it, and you’re done with the settings side.

Step 4: Push and Watch It Go!

Commit your new workflow file and config changes, then push your branch!

Go to the Actions tab in your repo and you’ll see the workflow running. Once it finishes, your project will be live at: https://your-username.github.io/your-repo-name/

From this point on, every push to your deployment branch triggers the whole process automatically: tests first, then build, then deploy. No more thinking or manual deployment!

--

--

coderSloth
coderSloth

Written by coderSloth

Web developer, educator, Max programmer, Arduino chef, artist @ 84collective.com, linkedin.com/in/rupadhillon/, rupadhillon.com