3 minute read โ€ข โ€ข Last updated on

Deploying Gatsby site on GitHub Pages


There are a couple of ways to deploy a Gatsby site to GitHub pages. In this tutorial I'll walk you through three approaches I find to be useful.

Do check out the official Gatsby documentation for this course of action first.

How SSG in Gatsby works

Gatsby is a free and open source framework based on React that helps developers build blazing fast websites and apps. One of the primary use case of Gatsby is Static Site Generation(SSG), which is useful for deploying personal websites with more granular control.

Typical Gatsby directory structure is as follows.

|-- /.cache
|-- /plugins
|-- /public
|-- /src
    |-- /api
    |-- /pages
    |-- /templates
    |-- html.js
|-- /static
|-- gatsby-config.js
|-- gatsby-node.js
|-- gatsby-ssr.js
|-- gatsby-browser.js

When you run gatsby build command, the public directory gets populated with static files optimized for production. The content of the public directory is what you will want to deploy in your website.

Deployment strategies

You can navigate to the next two strategies from the table of contents in the top right hand corner.

Naive approach

In a Gatsby project the public directory is usually added in the .gitignore file. But there is no stopping from intializing the public directory as a git repo and setting its remote to your GitHub repository.

git init public -b main
cd public
git add .
git commit -m"First commit"
git remote add origin <REMOTE_URL>
git remote -v
git push origin main

You can use the gatsby build command to generate the static files in the public directory. Every time you have to deploy, you can add, commit and push the files inside public directory. One can also write a custom deployment script in package.json, which executes whenever npm run deploy is executed in Gatsby project's root directory.

    "deploy": "gatsby build --prefix-paths && ./deploy.sh",

where deploy.sh contains,


cd public/
git add .
git commit -m"Updated"
git push origin main

You can immediately see the shortcomings of this approach. Creating two repositories for the same project is not the best practice. Moreover, the shell script would not run on Windows OS without major workarounds. There is the option of writing a custom script deploy.js but then again, it requires effort for something with tidy alternatives. Which brings us to the second approach.

The gh-pages package

GitHub Pages provides the functionality of publishing a specific branch for your website. Go to your repository, and navigate to Settings > Pages > Source where you can set the branch from which the site is built. Now to push the static files to GitHub pages, we can either spend time and effort to write custom scripts, which when done right does offer flexibility.

But the easiest way is by using the gh-pages package.

npm install gh-pages --save-dev

Then similar to what we did on the naive approach, we can add custom script on package.json file which executes on npm run deploy.

    "deploy": "gatsby build && gh-pages -d public -b gh-pages",

See the article, Deploying to a path on GitHub Pages on the official Gatsby docs for sites deployed at path like username.github.io/reponame/

GitHub Actions

If you are new to GitHub Actions, it helps automate, customize, and execute your software development workflows right in your repository. You can discover, create, and share actions to perform any job you'd like, including CI/CD, and combine actions in a completely customized workflow.

First, we must create a YAML file defining workflow configuration in the .github/workflows directory. A workflow is a configurable automated process made up of one or more jobs. A basic workflow configuration file for Gatsby CI is given below.
Workflow syntax for GitHub Actions provides extensive syntactical information for workflow configuration file.

name: Gatsby CI

    branches: [main]

    branches: [main]

    runs-on: ubuntu-latest

        node-version: [12.x, 14.x, 16.x]

      - uses: actions/checkout@v2
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v2
          node-version: ${{ matrix.node-version }}
          cache: "npm"
      - run: npm ci
      - run: npm run build --if-present
      - run: npm test
      - name: Deploy ๐Ÿš€
        uses: JamesIves/github-pages-deploy-[email protected]
          branch: gh-pages # The branch the action should deploy to.
          folder: public
          repositoryName: deploy_to_repo #Skip this if deploying to same repo
          token: ${{ secrets.ACCESS_TOKEN }} #Skip this when deploying to same repo

Okay, so plenty of things need explaining in this YAML file. First, this automated process is performed on a push or on a pull request to the main branch. If these events are triggered, then a job is run on the latest Ubuntu build, performing installation, build and test on the 3 specified node versions.

Finally the contents of public folder is pushed to the gh-pages branch. This is a basic work configuration file. For pushing to a different repository, personal access token must be created from here. Copy that token and set it in Settings > Secrets > New repository secret your GitHub repository. This can now be accessed through ${{ secrets.SECRET_NAME }} in the YAML file.

Get in touch ๐Ÿ‘‹

Feel free to email me about anything. Want some advice? Give some feedback?

You can also reach me around the web: GitHub, Twitter, Instagram