Vue-router redirect on page not found (404)

http-status-code-404, vue-router, vue.js

Solution

I think you should be able to use a default route handler and redirect from there to a page outside the app, as detailed below:

const ROUTER_INSTANCE = new VueRouter({
    mode: "history",
    routes: [
        { path: "/", component: HomeComponent },
        // ... other routes ...
        // and finally the default route, when none of the above matches:
        { path: "*", component: PageNotFound }
    ]
})

In the above `PageNotFound` component definition, you can specify the actual redirect, that will take you out of the app entirely:

Vue.component("page-not-found", {
    template: "",
    created: function() {
        // Redirect outside the app using plain old javascript
        window.location.href = "/my-new-404-page.html";
    }
}

You may do it either on `created` hook as shown above, or `mounted` hook also.

Please note:

I have not verified the above. You need to build a production version of app, ensure that the above redirect happens. You cannot test this in `vue-cli` as it requires server side handling.

Usually in single page apps, server sends out the same index.html along with app scripts for all route requests, especially if you have set `<base href="/">`. This will fail for your `/404-page.html` unless your server treats it as a special case and serves the static page.

Let me know if it works!

Update for Vue 3 onward:

You'll need to replace the `'*'` path property with `'/:pathMatch(.*)*'` if you're using Vue 3 as the old catch-all path of `'*'` is no longer supported. The route would then look something like this:

{ path: '/:pathMatch(.*)*', component: PathNotFound },

See the docs for more info on this update.

Problem

I'm trying to redirect to 404.html on page not found using the `router.beforeEach` global hook, without much success (using `Vue`and `Vue-Router` 1.0): ``` router.beforeEach(function (transition) { if (transition.to.path === '/*') { window.location.href = '/404.html' } else { transition.next() } }); ``` This is not redirecting to page `404.html` when a non-existing route is inserted, just giving me an empty fragment. Only when hard-coding some-site.com/* will it redirect to the expected some-site.com/404.html I'm sure there's something very obvious here that I'm overlooking, but I cannot figure out what. Please note that what I am looking for is a redirect to a new page, not a redirect to another route, which could be easily achieved by using `router.redirect` such as in these snippets: ``` router.redirect({ '*': '404' }) ``` Whereas on my `router.map`, I could have the following: ``` router.map({ '/404': { name: '404' component: { template: '<p>Page Not Found</p>' } } }) ```

Original source