Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.
Vue Router is a URL router that maps URLs to components.
In this article, we’ll look at how to use Vue Router’s history mode.
HTML5 History Mode
The default mode for Vue Router is hash mode. It uses a URL hash to simulate a full URL so that the page won’t be reloaded when the URL changes.
We can set Vue Router to history mode to get rid of the hash. It uses history.pushState
API to let us navigate URLs without a page reload.
For example, we can enable history mode as follows:
src/index.js
:
const Foo = { template: "<div>foo</div>" };
const Bar = { template: "<div>bar</div>" };
const routes = [
{
path: "/foo",
component: Foo
},
{
path: "/bar",
component: Bar
}
];
const router = new VueRouter({
mode: "history",
routes
});
new Vue({
el: "#app",
router
});
index.html
:
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="UTF-8" />
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<router-view></router-view>
</div>
<script src="src/index.js"></script>
</body>
</html>
Then when we go to /foo
and /bar
, we’ll see foo
and bar
displayed respectively. Now we don’t need to add a hash sign in front of the URL anymore.
Server Configuration
The issue with history mode is that we have to configure our server to display our app whenever the user navigates to the folder in our server.
This is because if we didn’t configure our server, we’ll get a 404 error if we go directly to the URL from the browser.
To fix this, we need to redirect to index.html
if it doesn’t match any assets uploaded to the server that we want to load.
We can use the following configure in Apache:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
This configuration assumes that the code is in the root folder. If it’s in a subfolder, we can change RewriteBase /
with RewriteBase /subfolder-name/
.
For Nginx, it’s simpler:
location / {
try_files $uri $uri/ /index.html;
}
Again, we can replace /
with the subfolder if the code is in a subfolder.
We should add a 404 route to our app since how 404 errors won’t be displayed.
We can add one as follows:
src/index.js
:
const Foo = { template: "<div>foo</div>" };
const Bar = { template: "<div>bar</div>" };
const NotFound = { template: "<div>not found</div>" };
const routes = [
{
path: "/foo",
component: Foo
},
{
path: "/bar",
component: Bar
},
{ path: "*", component: NotFound }
];
const router = new VueRouter({
mode: "history",
routes
});
new Vue({
el: "#app",
router
});
index.html
:
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="UTF-8" />
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<router-view></router-view>
</div>
<script src="src/index.js"></script>
</body>
</html>
With Node.js, the easiest way to serve a Vue app with history mode set by using Express and the connect-history-api-fallback
middleware as follows:
server.js
:
const express = require('express');
const history = require('connect-history-api-fallback');
const app = express();
app.use(history());
app.use(express.static('src'));
app.get('/', (req, res) => {
res.sendFile('src/index.html');
});
app.listen(3000, () => console.log('server started'));
Then the Vue app files can be stored in the src
folder.
In the code above, the code:
{ path: "*", component: NotFound }
is the catch-all route for anything other than foo
and bar
and maps to the NotFound
component.
Conclusion
We can enable the Vue Router’s history mode to eliminate the hash from our app’s URLs.
However, we have to redirect our app to index.html
since we don’t want users to see errors when they go the URLs by entering it or refreshing the page.
We can do this with any web server. Then we have to add a catch-all route to display something when it doesn’t match any routes.