Vue-router defaults to hash mode — the hash of a URL is used to simulate a full URL so that the page does not reload when the URL changes.

If you don’t want ugly hashes, you can use the history mode of the route, which takes full advantage of the history.pushState API to do URL jumps without reloading the page.

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

When you use history mode, the URL looks like a normal URL, such as yoursite.com/user/id, which also looks good…

However, this mode to play well, but also need background configuration support. Because our application is a single-page client application, if the background is not properly configured, when the user accesses oursite.com/user/id directly from the browser, it will return 404, which is not pretty.

So, you add a candidate resource on the server that covers all cases: if the URL doesn’t match any static resource, it should return the same index.html page that your app relies on.

Back-end configuration examples

Note: The following examples assume that you are serving the application from the root directory. If you want to deploy to a subdirectory, you need to use the publicPath option of the Vue CLI and the associated Router Base property. You also need to change the root directory in the following example to a subdirectory (for example, RewriteBase /name-of-your-subfolder/ instead of RewriteBase /).

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>
Copy the code

In addition to mod_rewrite, you can also use FallbackResource.

nginx

location / {
  try_files $uri $uri/ /index.html;
}

Copy the code

The original 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)
})

Copy the code

#Node.js-based Express

For Node.js/Express, consider using the connect-history-API-Fallback middleware.

#Internet Information Services (IIS)

  1. Install IIS UrlRewrite
  2. Create one in the root directory of your siteweb.configFile, as follows:
<? xml version="1.0" encoding="UTF-8"? > <configuration> <system.webServer> <rewrite> <rules> <rule name="Handle History Mode and custom 404/500" stopProcessing="true">
          <match url="(. *)" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          <action type="Rewrite" url="/" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

Copy the code

#Caddy

rewrite {
    regexp .*
    to {path} /
}

Copy the code

#Firebase host

Add the following to your firebase.json:

{
  "hosting": {
    "public": "dist"."rewrites": [{"source": "* *"."destination": "/index.html"}}}]Copy the code

warning

Be warned, because by doing so, your server will no longer return a 404 error page because the index.html file will be returned for all paths. To avoid this, you should overwrite all routing cases in the Vue application and then render a 404 page.

const router = new VueRouter({
  mode: 'history',
  routes: [
    { path: The '*', component: NotFoundComponent }
  ]
})

Copy the code

Or, if you’re using a Node.js server, you can use a server-side route to match incoming urls and return 404 if no route is matched for fallback. See the Vue server rendering documentation for more details.