Deploy a Vue/React app to GH Pages
Tags: actionshackathon21, vue, javascript, githubactions
Published: 2021-12-03 11:32:51

This guide takes you through how to deploy a Node app with GitHub Actions so that the static output can be served as GH Pages. This works well for Single-Page Applications, such as if using React or Vue.


## Submission category

This is my submission to [GitHub Actions Hackathon](https://dev.to/devteam/join-us-for-the-2021-github-actions-hackathon-on-dev-4hn4) under **DIY Deployments**.


## How it works

1. My workflow will be triggered by any pushes to `master` and any Pull Requests against `master`. Any changes to the `docs` directory will not trigger the workflow, as there is no point in rebuilding the app in that case.
1. The GitHub Actions environment already includes Node and Yarn, so if you don't care about the specific versions needed, you can leave out setup steps. For more control, see [Node workflows](https://michaelcurrin.github.io/code-cookbook/recipes/ci-cd/github-actions/workflows/node/).
1. There are shell steps to install NPM dependencies, run checks (linting and formatting) and then build the app. You can use `npm` or `yarn` in the steps.
1. The final step uses an Action which will take the unversioned output in the `dist` directory and commit it to the root of the `gh-pages` branch. For Vue, `dist` is typical, while React projects use `build`. 

The repo should configured to serve the `gh-pages` branch as a site.


## Sample YAML file

Create a workflow as `.github/workflows/main.yml` in your repo.

```yaml
name: Deploy GH Pages

on:
  push:
    branches: master
    paths-ignore:
      - "docs/**"

  pull_request:
    branches: master
    paths-ignore:
      - "docs/**"

jobs:
  build-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout 🛎️
        uses: actions/checkout@master
        with:
          persist-credentials: false

      - name: Install 🔧
        run: yarn install    # OR npm install

      - name: Lint 🧐
        run: yarn lint:check # OR npm run lint:check

      - name: Build 🏗️
        run: yarn build      # OR npm run build
        env:
          NODE_ENV: production

      - name: Deploy to GH Pages 🚀
        if: ${{ github.event_name != 'pull_request' }}
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: dist
```

Note that you don't have to generate or set a token - a [token](https://michaelcurrin.github.io/code-cookbook/recipes/ci-cd/github-actions/tokens/) will be generated for you by GH Actions. A token which only has access to the current repo and no human will need to interact with the token.

After committing the above file, check your _Actions_ tab and wait for the workflow to run.

After it is successful, go to repo settings and enable _Pages_ against the root of your `gh-pages` branch, to serve that as a GH Pages site. 

Then check the _Environment_ section to see it deployed.

Note also that the actual deploy step _only_ runs against `master` commits directly and _not_ on a Pull Request. So you can safely have your test and build steps run against a feature branch on a Pull Request for quality control, _without_ actually deploying anything until the PR gets merged.


## Workflows in use

### Vue

I have a `vue-quickstart` repo which was generated with Vue CLI and then extended with documentation, CI/CD, and demo site.

{% github MichaelCurrin/vue-quickstart %}

See [main.yml](https://github.com/MichaelCurrin/vue-quickstart/blob/master/.github/workflows/main.yml) there.

### React

I did the same thing for React:

{% github MichaelCurrin/react-quickstart %}

See [main.yml](https://github.com/MichaelCurrin/react-quickstart/blob/master/.github/workflows/main.yml) there.


## Resources

### On Code Cookbook

I have a ton of GH Actions workflows you can browse here:

- [Workflows | Code Cookbook](https://michaelcurrin.github.io/code-cookbook/recipes/ci-cd/github-actions/workflows/)

### On my Dev Resources site

- [Node](https://michaelcurrin.github.io/dev-resources/resources/javascript/node-js/) resources
- [GH Actions](https://michaelcurrin.github.io/dev-resources/resources/ci-cd/github-actions/) resources
- [GH Pages](https://michaelcurrin.github.io/dev-resources/resources/web/github-pages.html) resources
- [Vue](https://michaelcurrin.github.io/dev-resources/resources/javascript/packages/vue/vue-3.html) resources
- [React](https://michaelcurrin.github.io/dev-resources/resources/javascript/packages/react/) resources

### More template repos

No Node or CI needed here! These use CDN URLs to load React or Vue in the browser and that static HTML gets served directly on GH Pages without a build step.

- [react-frontend-quickstart](https://github.com/MichaelCurrin/react-frontend-quickstart)
- [vue-frontend-quickstart](https://github.com/MichaelCurrin/vue-frontend-quickstart)


## Credits

Photo by <a href="https://unsplash.com/@andriklangfield?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Andrik Langfield</a> on <a href="https://unsplash.com/s/photos/build?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>