Configure Html5 History Mode in VueJS and Apache

How to remove the unwanted hashbang in the URL of your routes by setting html5 history mode.

Monica Saiz
Dev Genius
Published in
3 min readJan 23, 2021

--

Photo by Jan Baborák on Unsplash

When building an app using a framework, sometimes you need to configure some routes. If you are working with frameworks like AngularJs or VueJs, you might get a free hashbang (#!)in the URL of your routes, which can be annoying.

This means we will get #!/myUrl, when what we want /myUrl .

A way to solve this problem is by setting a html5 history mode in your routes file. You might find this solved on the web, for example, in this post in StackOverflow. However, when I implemented it in my code, I faced problems. That’s why I’d like to share with you how I did it and how I solved those issues, hoping it can be of help to anyone.

The way to do this will change depending on which framework you use. I will explain how I do it in VueJs.

First, let’s remove the hashbang from the URLs.

In VueJs, to remove the hashbang, you need to set the mode as history in your router.js. This mode will take advantage of the history.pushState from Vue to achieve our navigation without a page reload:

const router = new VueRouter({
routes: […],
root: '/',
mode: 'history'
});

If you try to run your app now, the hashbang will have disappeared. But if you try to refresh any URL which is not the root one, you will get either a blank page or an error.

So this is how I solved this in both development and production modes:

In development

I am using browser-sync to hot reload my app while I’m coding, so I had to configure the task in my gulpfile.js related to browser-sync to use the npm package connect-history-api-fallback.

Therefore I added in the corresponding task in my gulpfile.js this:

var historyApiFallback = require('connect-history-api-fallback');gulp.task('browser-sync', function () {
return browserSync.init({
open: true,
port: 3001,
startPath: 'index.html',
notify: false,
server: {
baseDir: ['.'],
middleware: [ historyApiFallback() ]
}
});
});

Notice the line that says middleware: [historyApiFallback]. That’s where you are asking browser-sync to use html5 history mode to achieve our navigation without a page reload.

But in production, we need to be careful to configure our application webserver accordingly to this mode; otherwise, every time we refresh the page in any other than the root (index.html), we will probably get a 404.

In production

It would be best if you remembered to also add some configuration on the server where your app will be hosted, to allow the app to run in all routes, and to be able to refresh the page anytime.

I am using apache in my ubuntu server to serve all my sites, so what I did it’s to add a .htaccess file to the root of my application, in the same route as my index.html. I read that some people add it in the root of their apache configuration instead.

This is how it looks:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>

Restart the apache service (service apache2 restart) and refresh your site.

All routes might be working now.

Possible error

If, after making these changes, you get an error in the console saying:

Uncaught SyntaxError : Unexpected Token <

That might be because the browser is expecting JavaScript, but it is returning HTML as a result.

You should take a look at your index.html and at all the paths defined on it. You are possibly not pointing to the right paths, and therefore your server does not know how to mount the app.

For example, do not set src=”main.js” but src=”/main.js”.
This last bit also saved my day!

I hope all this is of some help to you!

--

--

I write about my learning in tech, wishing that it could be of help for anyone that one day had the same questions I had. My personal profile is @monifasol.