Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue Router, GitHub Pages, and Custom Domain Not Working With Routed Links

My domain: myname.com
My GitHub repo: myname
My GitHub name: myname

Underlying GH-Pages URL: myname.github.io/myname

My Issue: I have the following pages set up with a History Vue Router: home, contact, projects.
Whenever I go to myname.com/contact, it routes me to 404 instead. When I click on a link to redirect me to /contacts, it pushes it to the address bar but if you refresh, it routes to 404. I have read posts such as: Deploy Vue to GitHub Pages. Error with vue-router and Vue router on page refresh gets 404 but the issue persists and the custom domain is an added complexity. I have also read this: Vue Router return 404 when revisit to the url but, there is an example of a React Router page with a Browser Router working on GH-Pages: https://milosrancic.github.io/reactjs-website/activities, repo: https://github.com/milosrancic/reactjs-website.

Here is what I have done:

  • My package.json has the following line: "homepage": "https://myname.com/"
  • My vue.config.js is exactly this:
module.exports = {
    publicPath: '/'
  }
  • My Router is on my path: /src/router/index.js, passed into main.js new Vue(), and is exported like this:
export default new VueRouter({
    base: process.env.BASE_URL,
    mode: 'history',
    routes
})
  • Inside my App.vue (entry component), the template looks like this:
<template>
  <div id="app">
    <nav-bar></nav-bar>
    <router-view></router-view>
  </div>
</template>
like image 521
Alex Diamond Avatar asked Sep 06 '25 15:09

Alex Diamond


1 Answers

I was unable to fix the problem through Vue but, as tao mentioned, this is likely an issue with GitHub and how they handle URLs. The simplest fix is to use a Hash Router instead so that the entry URL stays static. However, this will introduce that, arguably distasteful /#/ in your URL.

Given how catch-all routes are not supported natively, someone has found a workaround for this: https://github.com/rafgraph/spa-github-pages. Note: This is likely not good for SEO because the intended URLs do not actually exist. This is doing a trick with their 404 redirects and handling it on the index page. This was for a portfolio site and as such, I am ok with this for now. If I, or someone else, finds a better solution, this will be updated.

Workaround:

Inside /public add a file called 404.html and paste the following contents:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>CHANGE THIS TO YOUR TITLE</title>
    <script type="text/javascript">
      // MIT License
      // https://github.com/rafgraph/spa-github-pages
      // This script takes the current url and converts the path and query
      // string into just a query string, and then redirects the browser
      // to the new url with only a query string and hash fragment,
      // e.g. https://www.foo.tld/one/two?a=b&c=d#qwe, becomes
      // https://www.foo.tld/?/one/two&a=b~and~c=d#qwe
      // Note: this 404.html file must be at least 512 bytes for it to work
      // with Internet Explorer (it is currently > 512 bytes)

      // If you're creating a Project Pages site and NOT using a custom domain,
      // then set pathSegmentsToKeep to 1 (enterprise users may need to set it to > 1).
      // This way the code will only replace the route part of the path, and not
      // the real directory in which the app resides, for example:
      // https://username.github.io/repo-name/one/two?a=b&c=d#qwe becomes
      // https://username.github.io/repo-name/?/one/two&a=b~and~c=d#qwe
      // Otherwise, leave pathSegmentsToKeep as 0.
      var pathSegmentsToKeep = 0;

      var l = window.location;
      l.replace(
        l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') +
        l.pathname.split('/').slice(0, 1 + pathSegmentsToKeep).join('/') + '/?/' +
        l.pathname.slice(1).split('/').slice(pathSegmentsToKeep).join('/').replace(/&/g, '~and~') +
        (l.search ? '&' + l.search.slice(1).replace(/&/g, '~and~') : '') +
        l.hash
      );

    </script>
  </head>
  <body>
  </body>
</html>

Inside /public/index.html, add the following inside the <head> right after <title>:

<script type="text/javascript">
// MIT License
// https://github.com/rafgraph/spa-github-pages
// This script checks to see if a redirect is present in the query string,
// converts it back into the correct url and adds it to the
// browser's history using window.history.replaceState(...),
// which won't cause the browser to attempt to load the new url.
// When the single page app is loaded further down in this file,
// the correct url will be waiting in the browser's history for
// the single page app to route accordingly.
(function(l) {
    if (l.search[1] === '/' ) {
    var decoded = l.search.slice(1).split('&').map(function(s) { 
        return s.replace(/~and~/g, '&')
    }).join('?');
    window.history.replaceState(null, null,
        l.pathname.slice(0, -1) + decoded + l.hash
    );
    }
}(window.location))
</script>

This has worked for me and I can now visit the contacts page by simply entering myname.com/contact. This should also work if you have nested SPA inside /public, using the same trick.

like image 173
Alex Diamond Avatar answered Sep 08 '25 15:09

Alex Diamond