Frustrated with Github.io, because you can't run your Quasar SPA in history mode? Well, now you can!
Introduction
This article is intended to help you get your SPA published on Github.io with history mode turned on. This isn't a straight up process, so I figured I'd write some instructions on how to do it, to help out others who might be running into problems with this process.
Vue-Router
Vue-Router has two modes; 1) hash and 2) history.
With hash mode, there is only a single web page and routing takes over to display your pages correctly. Any backend server will be set up to serve only the index file.
With history mode, the concept is similar. However, the server is expecting static pages and for it to be handling the routing. If you have control over your own server, you would write some rewrite rules so the index file will be loaded, and just the index file, for every page, so the vue-router can take over from there.
So, you might also be asking yourself...
If hash mode works fine on github.io, why would anyone want to use history mode?
For myself, I wanted to be able to use anchor links. So, given a url with a hash symbol in it, the proper page will load up and content will automatically scroll to the anchor link.
The Conumdrum with Github.io
At the time I was investigating this, github.io didn't allow you to write any sort of server rewrite rules. The information I found was sparse. Maybe it can be done, as I did this a while ago and things change. I can only tell you what worked for me then and still works for me now.
publicPath
Inside your quasar.conf.js
you can set up the publicPath
. What this does is put the public path data from the publicPath
variable in front of all your resource calls.
build: {
vueRouterMode: 'history',
publicPath: 'app-extension-qmarkdown',
Notice the publicPath
? This is for my component, QMarkdown, which lives at https://github.com/quasarframework/app-extension-qmarkdown. And, the github.io url would be this: https://quasarframework.github.io/app-extension-qmarkdown.
Using this publicPath
allows me to develop locally and then, when I build the site, the publicPath
is injected so resources can properly be found by the browser.
The 404 on Github.io
If you drop a 404.html into root of your SPA app, when a page is not found, it will be called. Since vue-router will be managing the routing, this 404.html page will be called for any presumably static page that doesn't exist (meaning, all your routes!).
I came up with a way to leverage this 404.html file. It took a while (over a week) to figure this all out and finalize it.
Basically, this is what your 404.html should look like:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>404 Redirect</title>
<script>
sessionStorage.redirect = location.href;
</script>
<meta http-equiv="refresh" content="0;URL='/app-extension-qmarkdown'"></meta>
</head>
<body>
</body>
</html>
Notice the meta
tag with URL. This needs to match your publicPath
route in order for it to work.
You may also be wondering why there are all the spaces between the body
tags. There was some issue with Internet Explorer. If the file was too small, it just wouldn't read it.
The Last Trick
The 404.html is running a snippet of JavaScript to put the current route into sessionStorage
. This is key to getting this all to work. We have to use this sessionStorage
to get back on track with vue-router.
In your index.template.html
file, you can add the following between the body tags:
<body>
<script>
(function(){
let redirect = sessionStorage.redirect;
delete sessionStorage.redirect;
if (redirect && redirect !== location.href) {
history.replaceState(null, null, redirect);
}
})();
</script>
<!-- DO NOT touch the following DIV -->
<div id="q-app"></div>
</body>
As you can see, sessionStorage
is read, deleted and then history is put back in place. Now, vue-router can take over without issues occurring in the browser.
Final Words
The above happens so fast, you would never know what's happening behind the scenes.
It is my hope that this helps others leverage github.io in history mode, just as it has helped me.
Are you using Github.io for publishing your SPA? Let's us also know your experiences or give us feedback about this article. We'd love to hear from you.
Interested in Quasar? Here are some more tips and information:
More info: https://quasar.dev
GitHub: https://github.com/quasarframework/quasar
Getting Started: https://quasar.dev/start
Chat Server: https://chat.quasar.dev/
Forum: https://forum.quasar.dev/
Twitter: https://twitter.com/quasarframework
Donate: https://donate.quasar.dev
Top comments (4)
Hi team, may I know how to set the spa as
history mode
? I get the 404-page-not-found when try to accesshttp://localhost:9000/second-page
.Nice article. I'm looking at trying similar on Netlify.
So the publicPath variable is only necessary because you are hosting the site starting from a subpath instead of at the root?
Yes, it's because the path is more that the root path.
anyone tried if this is still needed?
i think my page works without the hacks..
or at least party?
(i have included the 404.html with your redirect example)
but i am not entirely sure..