I have set up my vue-cli version 3 SPA so that any requests not found in my routes.js file will default to my 404 view as shown in the official documentation:
Inserted near bottom of routes.js file:
{ // catches 404 errors
  path: '*',
  name: '404',
  component: () => import(/* webpackChunkName: "NotFoundComponent" */ './views/NotFoundComponent.vue'),
},
Inserted into nginx configuration file:
location / {
  try_files $uri $uri/ /index.html;
}
This successfully alerts the user that the page they requested doesn't exist.
My Question:
I would like for the error 404 component to return a 404 response header (it current returns the 200 status code) and also log this error to the nginx error.log file. I imagine this is only possible through using nginx configuration. Has anyone achieved this goal?
I noticed that this issue is addressed in the following page in the vue-cli official docs, but it only is concerned with node express servers and not nginx: https://router.vuejs.org/guide/essentials/history-mode.html#caveat
I think it is similar to Node solution - you should repeat all your routes in nginx config to return 404 status code correctly, the main idea is that you should use "equals" modifier in locations and define error_page to return same index.html file but with 404 status code, example:
server {
    listen       80;
    server_name  localhost;
    root /my/dir/with/app
    error_page  404 /index.html;
    location = / {
        try_files $uri $uri/ /index.html;
    }
    location = /books {
        try_files $uri $uri/ /index.html;
    }
    # example nested page
    location = /books/authors {
        try_files $uri $uri/ /index.html;
    }
    # example dynamic route to access book by id
    location ~ /books/\d+$ {
        try_files $uri $uri/ /index.html;
    }
}
Probably this config can be simplified or improved because I am not very good at nginx configuration but it works.
I solved this the easy way by breaking out of the Vue ecosystem else it wont work or would take a lot of effort.
Make the following route in your Vue router:
{
  path: '*',
  name: 'PageNotFound',
  component: PageNotFound
}
The PageNotFound component should have the following code:
<script>
export default {
  name: 'PageNotFound',
  created() {
    window.location.href = "/404/"
  }
}
</script>
The nginx config should return a 404 on getting /404/ route:
server {
    ...
    location ~ ^/404/$ {
        return 404;
    }
    ...
}
I don't think it would work in a server side rendering environment. In such a case you might need to put the statement containing window.location.href in the mounted method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With