DEV Community

Debbie O'Brien
Debbie O'Brien

Posted on

When Netlify gives you that 404 page

Ever deployed a Vue or Nuxt app to Netlify and got a 404 page when you refresh? Yeah what is all that about.

Well if you are working with Vue or have Nuxt as a Single Page Application then your site is a single page so the route of your page isn't really a page like for example mysite.com/blog. Blog is your page but it is really your view that gets put into your index.html when rendered. Blog doesn't really exist as a page it is all that magic that goes on to make single page applications feel like they have lots of pages but they are in fact called single page applications because they only have a single page.

So basically when someone refreshes the page Netlify is looking for that page called blog and can't find it because it isn't really a page. So we need to tell Netlify that if you refresh or if someone lands on that page without going first through the home page to basically redirect them to the home page so that JavaScript can do its magic and the view you want can be rendered.

We can easily achieve this by adding a _redirects file (yes just like this, _redirects, nothing at the end of it) to our public folder with some redirect rules:

/*    /index.html   200
/*    /index.html   404
Enter fullscreen mode Exit fullscreen mode

Then if you refresh the page or send a link to someone it will work perfect.

Now if you are using Nuxt there is an easier way. There is always an easier way with Nuxt, however you can still use the redirects file if you want, you would just have to put it in your static folder and change index.html to 200.html as that is the default page in nuxt.

But instead of having to do that you can just create a generate property in your nuxt.config and add the key of fallback with the value of true. This means that if Nuxt is in SPA mode to fallback to 200.html when a page can't be found. 200.html is the default value so setting true will give you this but you could add a string with 200.html if you wanted.

export default {
  generate: {
    fallback: true
  }
}
Enter fullscreen mode Exit fullscreen mode

Sometimes you will have cases where you have a Nuxt static generated site and you can't understand why some pages on refresh work and others don't. And yes adding fallback to true will fix this but you may not have any idea why it was working on some and not others. Let me explain how Nuxt static sites work.

Nuxt will generate a page for every .vue file in the pages folder. All these pages are automatically static pages. However sometimes we have dynamic content such as content coming from a blog. We create the dynamic page but nuxt can't create a page for each blog post as it doesn't know what the names of those pages are going to be. (Your site will still work as Nuxt will cleverly just turn those pages into a single page application instead of static pages). So in order to generate those static pages we need to use the generate property and we just tell Nuxt what routes to generate for example:

export default {
  generate: {
    routes: [
      '/blogpost/1',
      '/blogpost/2',
      '/blogpost/3'
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

And of course that would be a pain having to put the routes there every time we add a blog post so in this case what we should do is write a function that maps over all our blog posts:

generate: {
    routes: function () {
      return axios.get('https://my-api/blogposts')
      .then((res) => {
        return res.data.map((post) => {
          return '/blogposts/' + post.id
        })
      })
    }
Enter fullscreen mode Exit fullscreen mode

This will now generate a page for each blog post and we can test this out by using the generate command and reading what gets printed in your terminal. You will then see what posts got generated and what didn't. You can also check this in the Netlify deploy logs.

If you want to read up more on how to deploy to Netlify with Nuxt then please see the Nuxt docs

Also check out the free video from Vue School on how to deploy

Oldest comments (14)

Collapse
 
swsalim profile image
Yuyu

Does it work with ServerMiddleware?

I created a serverMiddleware in my Nuxt app that makes this call for example, /api/fetch?url=<user_submitted_url>. While it works on Heroku, my app gives me 404 error whenever it tries to make that call.

I've tried added fallback: true to generate in the config with no luck.

Do you encounter this before?

Collapse
 
debs_obrien profile image
Debbie O'Brien

Hey, not come across that no. Did you manage to fix t?

Collapse
 
swsalim profile image
Yuyu

Yea. Apparently, these issues aren't related. The serverMiddleware doesn't work on static hosting hence it doesn't work on Netlify. I replaced the serverMiddleware with Netlify functions.

Thread Thread
 
debs_obrien profile image
Debbie O'Brien

Nice 👏

Collapse
 
rsmithlal profile image
Robert Smith

Thank you for this! Your redirects snippet really saved the day for me.

Collapse
 
tngeene profile image
Ted Ngeene

Hey, thank you for the post. would this still work with firebase? I can't seem to find proper documentation for deploying nuxt in spa mode on firebase.

Collapse
 
debs_obrien profile image
Debbie O'Brien

Hey, I have never worked with firebase but I found this article. hope it helps

Collapse
 
tngeene profile image
Ted Ngeene

thank you! yes, it did help.

Collapse
 
milos7811 profile image
Miloš Holba

Thanks ! It's work well !

Collapse
 
alexanderbenerink profile image
adb

Thank you so much.

Collapse
 
aviramontesn profile image
AViramontesN

Hi! Is there a way to fix this with just Vue? I'm not using either Nuxt or Netlify, just plain Vue.js. Would I have to add some kind of fix on the router files? Thank you.

Collapse
 
debs_obrien profile image
Debbie O'Brien

hey sorry not too sure. haven't tried it but am sure it will work somehow. maybe just creating the 404 file.

Collapse
 
archyscript profile image
Daniel Dasaolu

Yes

=> In your public folder
=> create a new file and name it "_redirects"
=> Paste this inside without the quote

"/* /index.html 200"

=> Save your file and push to github
=> It should work this way

Collapse
 
katieadamsdev profile image
Katie Adams

Saved my butt! Thank you :D