Directly from the Vue router web site.
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!
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>
nginx
location / {
try_files $uri $uri/ /index.html;
}
Native Node.js
const http = require('http')
const fs = require('fs')
const httpPort = 80
http.createServer((req, res) => {
fs.readFile('index.htm', 'utf-8', (err, content) => {
if (err) {
console.log('We cannot open "index.htm" file.')
}
res.writeHead(200, {
'Content-Type': 'text/html; charset=utf-8'
})
res.end(content)
})
}).listen(httpPort, () => {
console.log('Server listening on: http://localhost:%s', httpPort)
})
[0] https://router.vuejs.org/en/essentials/history-mode.html