Categories
JavaScript Vue

Using Vue Router’s History Mode

Spread the love

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.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published.