SoFunction
Updated on 2025-04-05

Configuration method and principle of Vue Router history mode

vue-routerDivided intohashandhistoryThe former is its default mode, and the expression of url is#home, relatively ugly. The url expression of the latter is/home, more beautiful.

But if you want to usehistoryMode, we need to make additional configuration in the backend. This article will discuss how to configure and why.

History mode configuration method

Let's take a look at the official documentation that teaches us how to configure: HTML5 History mode.

First of all,modeSet ashistory

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

Then set the backend (nginx used here):

location / {
 try_files $uri $uri/ /;
}

And then... it's gone! Obviously, the official tutorial is relatively brief, and we will actually encounter some problems when we refer to this tutorial.

Configuration practice and principle of history mode

Highly suggest: Before reading this part, take a look at this part of nginx documentation andThis part of the document

Since the official documentation teaches us to do this, let’s practice it as it says.

Only front-end configuration

First, we willmodeSet ashistory, but no backend is configured. Then, if our route looks like this:

const routes = [
  {path: '/home', component: Home},
  {path: '/', redirect: '/home'}
];

We deploy the project with nginx and enter it in the address barhttp://localhost:8080(The port configured here is 8080), you will find that the address bar will becomehttp://localhost:8080/home,andLooksEverything is normal,seemThe route can also be switched normally without other problems (there will actually be problems, which will be discussed later). It seems that you can also implement it without configuring the backend as the official website tells us.historyMode, but if you enter it directly in the address barhttp://localhost:8080/home, you will find that you have obtained a 404 page.

Sohttp://localhost:8080Why can it be displayed normally (partially)? The reason is actually very simple, you can visithttp://localhost:8080When the static server (nginx here) will go to the target directory by default (locationmiddlerootSearch under the specified directory)(This is the default behavior of nginx when there is no extra path behind the port), is there this file in the target directory? have! Then the static server returns you this file, and cooperatevue-routerIf forwarding is done, it can naturally be displayed (partially).

But if you visit directlyhttp://localhost:8080/home, the static server will search in the target directoryhomeFile, is there this file in the target directory? No! So naturally it's 404.

Configure the backend

In order to achieve direct accesshttp://localhost:8080/homeIt can also be successful. We need to make some configuration of the backend (here is nginx).

First of all, think about how to achieve this goal?

In the traditionalhashIn mode (http://localhost:8080#home), even if there is no need to configure, the static server will always look for itAnd return to us, thenvue-routerWill get it#The following characters are used as parameters to transform the front-end page.

Analogize,historyIn mode, what we want is:http://localhost:8080/home, but the one that returns in the end is also,Thenvue-routerWill get ithomeAs a parameter, transform the front-end page. So who can do this in nginx? The answer istry_files

First, let’s take a look at the syntax of try_files:try_files file ... uri;

Then take a look at the official documentation about it:

Checks the existence of files in the specified order and uses the first found file for request processing; the processing is performed in the current context. The path to a file is constructed from the file parameter according to the root and alias directives. It is possible to check directory's existence by specifying a slash at the end of a name, . “$uri/”. If none of the files were found, an internal redirect to the uri specified in the last parameter is made.

The general idea is that it will followtry_filesThe following parameters are matched in turnrootcorresponding file or folder in. If a file is matched, the file will be returned; if a folder is matched, the folder will be returned.indexThe file specified by the directive. The last oneuriThe parameter will be used as the fallback that did not match before. (Noticetry_filesThe instruction requires at least two parameters)

Take my own website as an example:

location / { 
    root      /data/www/rf-blog-web; 
    index      ; 
    try_files    $uri $uri/ /; 
}

$uriIt is a variable in nginx, for example, the URL I visited ishttp://localhost:8080/home, then it represents/home

existrf-blog-webThere is no subdirectory in this directory, only oneAnd some compressed .js files with hash values. When we requesthttp://localhost:8080/homeWhen this address, first look for anyhomeThis file, no; look for anyhomeDirectory, neither. So in the end, the third parameter will be positioned to return, according to this rule, the URL paths in all routes will be finally locatedvue-routerThen get the parameters to transform the front-end page, so we can already use ithttp://localhost:8080/homeThis address was successfully accessed.

and$uriThe function of this parameter is actually to match those .js files, and$uri/It is not very useful in this example, it can actually be removed.

historyProblems and solutions that may be encountered in mode

Changing my project (used lazy loading in the route) tohistoryDuring the mode process, sometimes you will find that the chunk loading error occurs. When you open the chrome network, you will find that the chunk loads 404 because there is an extra layer of path in the requested url. I found a solution here.

LinusBorg said, becausehistoryWhen switching routes in mode, we really change the url path of the page, so the webpack runtime will think it is located in/some/path. ifpublicPathis the relative path set, then webpack may become/some/path/static/js/Such a path, however the real path of chunk is/static/js/, so we need topublicPathSet to absolute path (publicPath: '/') to solve this problem.

Summarize

The above is the configuration method and principle of the Vue Router history mode introduced to you by the editor. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support for my website!