Vue-router history mode

I have an app using vuejs and webpack and the following routes

/
/search
/search/results
/search/results/film

Each routes component is lazy loaded using the following code

const Home = resolve => {
    require.ensure(['@app/Home.vue'], () => {
        resolve(require('@app/Home.vue'));
    }, 'home');
};

navigation between the routes is handled with router.go() or nav links at the top of the page. Everything works perfect when in ‘hash’ mode - but when using ‘history’ mode i start to get problems.

the route /search/results has a component with a <router-link> - the router-link links to the next page which of course is /search/results/film/:name - however when the router-link generated anchor is clicked i get an error as follows:

GET http://localhost:8080/search/results/1.js/main-36c1ade0c1f0a0a2b328.js 
Error: Loading chunk 1 failed.
    at HTMLScriptElement.onScriptComplete (main-36c1ade0c1f0a0a2b328.js:756)
//The router link used in the /search/results component template
<router-link :to="{ name: 'more-details', params: {film: film.name} }">...</router-link>

All the other routes are loading successfully and their GET requests are as follows:

http://localhost:8080/3.js/main-36c1ade0c1f0a0a2b328.js

so the url to the split/chunked JS files seems to be getting changed by something and search/results is being added, im not sure if the problem is webpack, vue-router, the router-link etc. When i switch back to hash mode routing from history mode everything works again. However i would like to use the history mode for the scrollBehaviour feature.

Please help.

thanks

Are you using relative paths for your output in webpack? That doesn’t play well with history mode

my output is as follows in webpack config is as follows

output: {
    path: path.resolve(__dirname, 'dist'),
    publicPath: '',
    filename: 'js/main-[hash].js'
  },

try publicPath: '/'

1 Like

wow, this worked!! Woohoo - can you explain the reasons as to why this is needed when it is not required for hash mode?

thanks

Well, in history mode, you actually change the page’s URL path, while in hash mode you are always at example.com/, you only change the hash, which is not part of the path, it’s origianally just used locally, by the browser to jump to elements with specific ids.

Now, when you change the path, the browser / webpack’s runtime thinks it’s at example.com/some/path

And since you defined a relative path as the publicPath, it will look for the chunk for the lazy-load component under that relative path, probably something like:
example.com/some/path/static/js/3.js

But that’s not where it lives, it lives at: example.com/static/js/3.js

…and using an absolute path forces the request to always go to that correct path.

4 Likes