362

How to remove hashbang #! from url?

I found option to disable hashbang in vue router documentation ( http://vuejs.github.io/vue-router/en/options.html ) but this option removes #! and just put #

Is there any way to have clean url?

Example:

NOT: #!/home

BUT: /home

Thanks!

Jerry Chong
  • 7,954
  • 4
  • 45
  • 40
DokiCRO
  • 4,565
  • 3
  • 20
  • 22

16 Answers16

621

In Vue 3, you'd want to use createWebHistory for the history option.

import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(),
  // ...
})

In Vue 2, you'd want to set mode to 'history'.

const router = new VueRouter({
  mode: 'history',
  // ...
})

Make sure your server is configured to handle these links, though. https://router.vuejs.org/guide/essentials/history-mode.html

nnnmmm
  • 7,964
  • 4
  • 22
  • 41
Bill Criswell
  • 32,161
  • 7
  • 75
  • 66
119

For vue.js 2 use the following:

const router = new VueRouter({
 mode: 'history'
})
kissu
  • 40,416
  • 14
  • 65
  • 133
Israel Morales
  • 1,681
  • 1
  • 14
  • 6
47

For Vue 3, change this :

const router = createRouter({
    history: createWebHashHistory(),
    routes,
});

To this :

const router = createRouter({
    history: createWebHistory(),
    routes,
});

Source : https://next.router.vuejs.org/guide/essentials/history-mode.html#hash-mode

Paul
  • 1,410
  • 1
  • 14
  • 30
35

Hash is a default vue-router mode setting, it is set because with hash, application doesn't need to connect server to serve the url. To change it you should configure your server and set the mode to HTML5 History API mode.

For server configuration this is the link to help you set up Apache, Nginx and Node.js servers:

https://router.vuejs.org/guide/essentials/history-mode.html

Then you should make sure, that vue router mode is set like following:

vue-router version 2.x

const router = new VueRouter({
  mode: 'history',
  routes: [...]
})

To be clear, these are all vue-router modes you can choose: "hash" | "history" | "abstract".

kissu
  • 40,416
  • 14
  • 65
  • 133
Tadas Stasiulionis
  • 1,316
  • 3
  • 16
  • 18
32

For Vuejs 2.5 & vue-router 3.0 nothing above worked for me, however after playing around a little bit the following seems to work:

export default new Router({
  mode: 'history',
  hash: false,
  routes: [
  ...
    ,
    { path: '*', redirect: '/' }, // catch all use case
  ],
})

note that you will also need to add the catch-all path.

kissu
  • 40,416
  • 14
  • 65
  • 133
Adil H. Raza
  • 1,649
  • 20
  • 25
16

Quoting the docs.

The default mode for vue-router is hash mode - it uses the URL hash to simulate a full URL so that the page won't be reloaded when the URL changes.

To get rid of the hash, we can use the router's history mode, which leverages the history.pushState API to achieve URL navigation without a page reload:

const router = new VueRouter({
  mode: 'history',
  routes: [...]
})

When using history mode, the URL will look "normal," e.g. http://oursite.com/user/id. Beautiful!

Here comes a problem, though: Since our app is a single page client side app, without a proper server configuration, the users will get a 404 error if they access http://oursite.com/user/id directly in their browser. Now that's ugly.

Not to worry: To fix the issue, all you need to do is add a simple catch-all fallback route to your server. If the URL doesn't match any static assets, it should serve the same index.html page that your app lives in. Beautiful, again!

kissu
  • 40,416
  • 14
  • 65
  • 133
Ankit Kumar Ojha
  • 2,296
  • 2
  • 22
  • 30
13
window.router = new VueRouter({
   hashbang: false,
   //abstract: true,
  history: true,
    mode: 'html5',
  linkActiveClass: 'active',
  transitionOnLoad: true,
  root: '/'
});

and server is properly configured In apache you should write the url rewrite

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.html$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.html [L]
 </IfModule>
kissu
  • 40,416
  • 14
  • 65
  • 133
vivek
  • 179
  • 1
  • 5
8

Several good descriptions above lead me into rabbit hole until I realized the "createWebHistory" which replaces "createWebHashHistory" exists in two places in the router/index.js file. Once in the definition of the constant at the end of the file and again on the import from vue-router at the top of the file.

Found down at the end of the router/index.js file

  const router = createRouter({
    mode: 'history',
    history: createWebHistory(),
    // history: createWebHashHistory(),
    routes
  })

First line in router/index.js file

import { createRouter, createWebHistory } from 'vue-router'
// import { createRouter, createWebHashHistory } from 'vue-router'

Now it works like a charm, thank you all above that lead me down this path to success!

Harvey Mushman
  • 615
  • 1
  • 11
  • 23
5

The vue-router uses hash-mode, in simple words it is something that you would normally expect from an achor tag like this.

<a href="#some_section">link<a>

To make the hash disappear

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
  },
] // Routes Array
const router = new VueRouter({
  mode: 'history', // Add this line
  routes
})

Warning: If you do not have a properly configured server or you are using a client-side SPA user may get a 404 Error if they try to access https://website.com/posts/3 directly from their browser. Vue Router Docs

Ritankar Paul
  • 65
  • 1
  • 4
4

Just replace createWebHashHistory with createWebHistory in router.js file

IGF
  • 41
  • 1
2
const router = new VueRouter({
  mode: 'history',
  routes: [...]
})

And if you are using AWS amplify, check this article on how to configure server: Vue router’s history mode and AWS Amplify

kissu
  • 40,416
  • 14
  • 65
  • 133
dmitriyeff
  • 21
  • 3
2

You should add mode history to your router like the below

export default new Router({
  mode: 'history',
  routes: [
    {
     ...
    }
  ]
})
kissu
  • 40,416
  • 14
  • 65
  • 133
Brahim SLIMANI
  • 310
  • 1
  • 8
1

The default mode for vue-router is hash mode - it uses the URL hash to simulate a full URL so that the page won't be reloaded when the URL changes. To get rid of the hash, we can use the router's history mode, which leverages the history.pushState API to achieve URL navigation without a page reload:

import {routes} from './routes'; //import the routes from routes.js    

const router = new VueRouter({
    routes,
    mode: "history",
});

new Vue({
    el: '#app',
    router,
    render: h => h(App)
});

routes.js

import ComponentName from './ComponentName';

export const routes = [
   {
      path:'/your-path'
      component:ComponentName
   }
]

Reference

kissu
  • 40,416
  • 14
  • 65
  • 133
Rijosh
  • 1,538
  • 1
  • 8
  • 11
  • 2
    While this code may provide a solution to the question, it's better to add context as to why/how it works. This can help future users learn, and apply that knowledge to their own code. You are also likely to have positive feedback from users in the form of upvotes, when the code is explained. – borchvm Mar 16 '20 at 12:54
1

Open the file in src->router->index.js

At the bottom of this file:

const router = new VueRouter({
  mode: "history",
  routes,
});
Shujat Munawar
  • 1,657
  • 19
  • 23
0

In Vue 3, you can use createWebHistory module provided by the package vue-router to get a clean URL.

import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(),
  // ...
})

There is also another module that keeps '#' symbols in the URL named createWebHashHistory, which helps the browser navigate to a particular element.

import { createRouter, createWebHashHistory } from 'vue-router'

const router = createRouter({
  history: createWebHashHistory(),
  // ...
})

You might prefer to use createWebHistory over createWebHashHistory, if you want no '#' symbols in the URL.

For more information feel free to check their docs: https://router.vuejs.org/guide/essentials/history-mode.html

0
import { createRouter, createWebHistory } from 'vue-router';
const router = createRouter({
history: createWebHistory(),
routes: [],
});


export default router;
  • 1
    Thank you for your interest in contributing to the Stack Overflow community. This question already has quite a few answers—including one that has been extensively validated by the community. Are you certain your approach hasn’t been given previously? **If so, it would be useful to explain how your approach is different, under what circumstances your approach might be preferred, and/or why you think the previous answers aren’t sufficient.** Can you kindly [edit] your answer to offer an explanation? – Jeremy Caney Jul 31 '23 at 00:14