How to Deploy a Vue.js Application with Dynamic Routing on GitHub Pages

The Problem

Dynamic routing in Vue.js is handled by vue-router. The default mode for vue-router is hash mode, which results in unusual-looking URLs and performs poorly in SEO. To make the Vue application more SEO friendly, we can use the router’s history mode, but a problem arises when we deploy our application to GitHub Pages — users will get a 404 error if they access a route directly in their browser.

This is because GitHub Pages does not natively support single-page applications (SPAs). When there is a fresh page load for a URL like https://<USERNAME>, where /test is a frontend route, the GitHub Pages server returns 404 because it knows nothing of /test.

Instructions for Deployment

Deploying a Vue.js application using dynamic routing on GitHub Pages is not straightforward and I had to patch many routing issues to get my application up and running. Hope this guide saves you the trouble of having to go through several web pages/forums to get your application deployed.

The instructions provided here are meant to be concise. Detailed explanations on how the codes work can be found in the references.

1. Set the correct publicPath in vue.config.js.

If you are deploying to https://<USERNAME> or to a custom domain, you can skip this step.

If you are deploying to https://<USERNAME><REPO-NAME>/, (i.e. your repository is at<USERNAME>/<REPO-NAME>), set publicPath to "/<REPO-NAME>/". For example, if your repo name is "my-project", your vue.config.js should look like this:

// vue.config.js file to be placed in the root of your repositorymodule.exports = {
publicPath: process.env.NODE_ENV === 'production'
? '/my-project/'
: '/'

2. Update router paths to include the repository name.

The routes variable should look similar to the following:

const routes = [
path: '/',
redirect: { name: 'Home' }
path: '/<REPO-NAME>/',
name: 'Home',
component: Home
path: '/<REPO-NAME>/:queryParams(.*)',
name: 'Result',
component: Result,
props: true

̶3̶.̶ ̶C̶o̶p̶y̶ ̶a̶n̶d̶ ̶p̶l̶a̶c̶e̶ ̶t̶h̶i̶s̶ ̶4̶0̶4̶.̶h̶t̶m̶l̶ ̶f̶i̶l̶e̶ ̶i̶n̶ ̶t̶h̶e̶ ̶s̶a̶m̶e̶ ̶d̶i̶r̶e̶c̶t̶o̶r̶y̶ ̶a̶s̶ ̶y̶o̶u̶r̶ ̶i̶n̶d̶e̶x̶.̶h̶t̶m̶l̶ ̶f̶i̶l̶e̶ ̶(̶u̶s̶u̶a̶l̶l̶y̶ ̶i̶n̶ ̶t̶h̶e̶ ̶p̶u̶b̶l̶i̶c̶ ̶d̶i̶r̶e̶c̶t̶o̶r̶y̶)̶.̶

̶I̶f̶ ̶y̶o̶u̶ ̶a̶r̶e̶ ̶s̶e̶t̶t̶i̶n̶g̶ ̶u̶p̶ ̶a̶ ̶P̶r̶o̶j̶e̶c̶t̶ ̶P̶a̶g̶e̶s̶ ̶s̶i̶t̶e̶ ̶a̶n̶d̶ ̶n̶o̶t̶ ̶u̶s̶i̶n̶g̶ ̶a̶ ̶c̶u̶s̶t̶o̶m̶ ̶d̶o̶m̶a̶i̶n̶ ̶(̶i̶.̶e̶.̶ ̶y̶o̶u̶r̶ ̶s̶i̶t̶e̶’̶s̶ ̶a̶d̶d̶r̶e̶s̶s̶ ̶i̶s̶ ̶<̶U̶S̶E̶R̶N̶A̶M̶E̶>̶.̶g̶i̶t̶h̶u̶b̶.̶i̶o̶/̶<̶R̶E̶P̶O̶-̶N̶A̶M̶E̶>̶)̶,̶ ̶t̶h̶e̶n̶ ̶y̶o̶u̶ ̶a̶l̶s̶o̶ ̶n̶e̶e̶d̶ ̶t̶o̶ ̶s̶e̶t̶ ̶p̶a̶t̶h̶S̶e̶g̶m̶e̶n̶t̶s̶T̶o̶K̶e̶e̶p̶ ̶t̶o̶ ̶ ̶i̶n̶ ̶t̶h̶e̶ ̶4̶0̶4̶.̶h̶t̶m̶l̶ ̶f̶i̶l̶e̶ ̶i̶n̶ ̶o̶r̶d̶e̶r̶ ̶t̶o̶ ̶k̶e̶e̶p̶ ̶/̶<̶R̶E̶P̶O̶-̶N̶A̶M̶E̶>̶ ̶i̶n̶ ̶t̶h̶e̶ ̶p̶a̶t̶h̶ ̶a̶f̶t̶e̶r̶ ̶t̶h̶e̶ ̶r̶e̶d̶i̶r̶e̶c̶t̶.̶

̶4̶.̶ ̶C̶o̶p̶y̶ ̶t̶h̶i̶s̶ ̶r̶e̶d̶i̶r̶e̶c̶t̶ ̶s̶c̶r̶i̶p̶t̶ ̶a̶n̶d̶ ̶a̶d̶d̶ ̶i̶t̶ ̶t̶o̶ ̶y̶o̶u̶r̶ ̶i̶n̶d̶e̶x̶.̶h̶t̶m̶l̶ ̶f̶i̶l̶e̶.̶

(Edit: Steps 3 and 4 still work, but there’s a simpler alternative. Create a file named 404.html in the same directory as index.html—usually in the public directory—and copy the contents of index.html into it. Thanks Klesun for pointing that out.)

5. Deploy the project to GitHub Pages.

Inside your project, create with the following content (with bolded lines uncommented appropriately) and run it to deploy:

#!/usr/bin/env sh# abort on errors
set -e
# build
npm run build
# navigate into the build output directory
cd dist
# if you are deploying to a custom domain
# echo '' > CNAME
git init
git add -A
git commit -m 'deploy'
# if you are deploying to https://<USERNAME>
# git push -f<USERNAME>/<USERNAME> main
# if you are deploying to https://<USERNAME><REPO>
# git push -f<USERNAME>/<REPO>.git main:gh-pages
cd -


Disclaimer: This article may contain extracts from these references.

  1. (Steps 1 and 5)
  2. (Steps 3 and 4)




Software Engineer.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Everything You Need to Know About Buying an Electric Car

best label printers for home and small businesses

The Necessity of Redefining Broadband

MediaTek announces a its new Helio G85 gaming chipset

The Weird [and Wonderful] Side of Smart Home Tech

Faith Technologies, EnTech Solutions add three solar microgrids to Bad River Tribe facilities in…

The OVR ARwards Winners Announcement

Augmented Reality for Manufacturing

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Hui Shun Chua

Hui Shun Chua

Software Engineer.

More from Medium

Publish a Vue App from GitHub Pages on a Custom Domain

Web server on windows for local development

Troubleshooting the CORS error

To-do Project