16

Has anyone managed to figure out how to make Vue.js work with history mode with GitHub or GitLab Pages?

It works with hash mode, but I don't want to use hash mode for SEO related reasons.

Reference for router modes: https://router.vuejs.org/en/essentials/history-mode.html

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
fisker
  • 979
  • 4
  • 18
  • 28

8 Answers8

11

I found a solution that works for me in this article.

To summarize the solution, I created the following 404.html file and added it to the project's root folder.

<!DOCTYPE html>
<html>
    <head>
        <script>
            // ====================================================================================================================
            // This text is simply to make sure the 404.html file is bigger than 512 bytes, else, internet explorer will ignore it.
            // Thank you internet explorer for requiring such awesome workarounds in order to work properly
            // ====================================================================================================================
            sessionStorage.redirect = location.href;
        </script>
        <meta http-equiv="refresh" content="0;URL='/'">
    </head>
</html>

I then added this javascript in the index.html:

(function(){
    var redirect = sessionStorage.redirect;
    delete sessionStorage.redirect;
    if (redirect && redirect != location.href) {
        history.replaceState(null, null, redirect);
    }
})();
Joel Bourbonnais
  • 2,618
  • 3
  • 27
  • 44
BobWithHair
  • 171
  • 1
  • 6
7

Not sure about GitLab Pages, but in GitHub Pages you can serve your whole Vue.js Application through the 404.html file instead of the index.html file. Simply rename the index.html file to 404.html file on deploy.

EDIT: As pointed out in the comments, this has the side effect of having GitHub/GitLab serve your website with a 404 status code.

Giorgio Acquati
  • 111
  • 1
  • 7
  • 2
    Worked for me 17/01/2021 in GitLab Pages – aimorris Jan 17 '21 at 07:51
  • 1
    one problem. Main page will return 404 status instead of 200. Because of that some other tools don't want to read my site. – noisy Jul 02 '21 at 11:16
  • 1
    Worked for me, 13/07/2021 in GitlabPages - GitlabEE 12.8.6 – eti_nne Jul 13 '21 at 19:55
  • If you care about SEO do not use this, this will tank your rankings on google. Use a proper fix and redirect back to the root file (index.html). – Alex Nov 27 '22 at 05:40
6

Run into same issue, found this question & tried both solution above but no luck. Then tried combine them like this:

Here my 404.html file

<!DOCTYPE html>
<html>
<head>
    <title>My App</title>
    <script>
        // ========================================
        // Credits:
        // - https://stackoverflow.com/a/50259501
        // - https://stackoverflow.com/a/50247140
        // ========================================
        const segment = 1

        sessionStorage.redirect = '/' + location.pathname.slice(1).split('/').slice(segment).join('/')

        location.replace(
            location.pathname.split('/').slice(0, 1 + segment).join('/')
        )
    </script>
</head>
</html>

And here's my main.js file

const app = new Vue({
    router,
    store,
    render: h => h(App),
    created () {
        if (sessionStorage.redirect) {
            const redirect = sessionStorage.redirect
            delete sessionStorage.redirect
            this.$router.push(redirect)
        }
    }
})

app.$mount('#app')

And it works

Fery W
  • 1,402
  • 1
  • 15
  • 28
6

GitLab Answer

For those using GitLab there is now support to redirect to index.html using a _redirects file in your public folder.

Steps:

  1. Create a file named _redirects in the public folder
  2. Add this snippet line to that file
    /* /index.html 200

Documentation: https://docs.gitlab.com/ee/user/project/pages/redirects.html#rewrite-all-requests-to-a-root-indexhtml

Alex
  • 61
  • 1
  • 3
  • 1
    if anyone is looking for an example, take a look at https://gitlab.com/WaldemarLehner/vite-vue3-vuerouter-gitlab-pages-starter (code) and https://waldemarlehner.gitlab.io/vite-vue3-vuerouter-gitlab-pages-starter/ (gitlab pages instance). This specific example uses Vite as its Bundler. – Waldemar Lehner Jul 12 '22 at 16:58
  • 1
    In my case this additional line `/_nuxt/* /_nuxt/:splat` worked also when using custom domains – Paolo Falomo Nov 26 '22 at 00:06
5

A little late to the party but I have a method to do this. I am using Vue CLI 3 and GitHub pages.

First of all, I commit all the source file into a source branch, and commit the dist folder (generated by Vue) to the master branch using the following shell command:

# deploy.sh

#!/usr/bin/env sh

# abort on errors
set -e


# build
echo Building. this may take a minute...
npm run build

# navigate into the build output directory
cd dist
# create a copy of index.html
cp index.html 404.html
find . -name ".DS_Store" -delete

# if you are deploying to a custom domain
echo 'custom.com' > CNAME

# remove git and reinitialise
rm -rf .git
echo Deploying..
git init
git add -A
git commit -m 'deploy'

# deploy
git remote add origin https://github.com/User/repo.github.io
git push origin master --force

cd -
rm -rf dist

When GitHub pages can't find the route, it uses 404.html. The deploy program I wrote makes a copy of index.html and names it 404.html. That's why it works.

Edit Just realised that this wouldn't be good for SEO purposes as it returns a 404 response and Google won't index it.

Palash Sharma
  • 662
  • 1
  • 10
  • 18
4

You could use a 404.html hack https://github.com/rafrex/spa-github-pages/blob/gh-pages/404.html

Or you can try to pre rendering your vue into static html https://nuxtjs.org/guide#static-generated-pre-rendering-

Morty Choi
  • 2,466
  • 1
  • 18
  • 26
2

Based on Fery's solution, I think instead of handling redirect when creating Vue instance, the Navigation Guards could work better.

I basically added a beforeEnter guard for the index route, so that the index page will be skipped and directly go to the target page.

const routes = [
{
  path: '/',
  component: Index,
  beforeEnter: (to, from, next) => {
    if (sessionStorage.getItem('redirect') !== null) {
      const redirect = sessionStorage.redirect
      delete sessionStorage.redirect
      next(redirect)
    } else {
      next()
    }
  }
},
]

Hope this is helpful.

Raymond Nook
  • 29
  • 1
  • 2
0

2021 Solution for vue3 & vue-cli:

Follow this with "Basic instructions":

https://github.com/rafgraph/spa-github-pages#usage-instructions

no need to change var pathSegmentsToKeep = 0; the 404.html.

and then in the vue.config.js:

  // do not use "./dist/"
  publicPath: "/dist/",
  // make the index.html file place at the root of the repo
  indexPath: "../index.html",

then the spa is good to go~

Jun Huang
  • 1
  • 1