Use Github Action to deploy React app to Surge

Reading Time: 2 minutes


  • Generate a personal access token and create ACCESS_TOKEN variable under Settings -> Secrets.
  • Keep the personal access token in a safe place and do not lose it

npm script commands

  • Add script commands “build” and “clean” to build application and generate artifacts in dist/ directory
  "scripts": {
    "dev": "parcel src/index.html",
    "build": "parcel build src/index.html",
    "clean": "rm -rf ./dist/"
  • Run “npm run build” to build static application before deployment to

Surge setup

  • npm install surge globally
npm install -g surge
  • Login or create account in command line
email: <email address>
password: <password>

project:  <project directory>/dist
domain: <custom domain>
  • After the site is published, verify http://<custom domain> can be browsed

Surge Token

  • Generate surge token in command line
surge token
XXXXXXXXX        <-- a surge token is issued by Surge
  • In Github repo, create SURGE_TOKEN variable under Settings -> Secrets.
  • Keep surge token in safe location such that it can be reused to deploy other applications to Surge.

Create Github Action workflow file

  • Go to Actions tab of the github repo
  • Create surge.yml under .github/workflow

Paste the follow code in the yaml file

name: Deploy to
    - master
     name: Deploying to surge
     runs-on: ubuntu-latest
       - name: Setup Node.js for use with actions
         uses: actions/setup-node@v1.1.0
           version:  12.x
       - name: Checkout branch
         uses: actions/checkout@v2
       - name: Clean install dependencies
         run: npm ci
       - name: Build app
         run: npm run build

       - name: Rename index.html to 200.html
         run: mv ./dist/index.html ./dist/200.html

       - name: Install Surge
         run: npm install -g surge
       - name: Deploy to Surge
         run:  surge ./dist https://<custom domain> --token ${{secrets.SURGE_TOKEN}}
  • Replace <custom domain> with actual surge domain name

Add 200.html page for Client-side routing

  • When page is refreshed in Surge, the url does not reach our Reach Router and default Surge 404 page is returned.
  • The solution is to rename dist/index.html to dist/200.html before deployment to Surge is carried out.
  • This is done by mv ./dist/index.html ./dist/200.html in surge.yaml
  • The reason is to load the app when 200 response is resulted. Then the app loads the appropriate component by matching the path of reach router to the url