Next.js: Reusing Error page gives "soft 404" in google webmasters

Created on 2 Aug 2017  路  9Comments  路  Source: vercel/next.js

Expected Behavior

When we are trying to render a custom 404 error page like https://github.com/zeit/next.js#reusing-the-built-in-error-page
The response status should also return a 404 status error along with the page.

Current Behavior

Currently, The statusCode gets passed as props and the page works fine, however the document(res) contains a status code of 200, which is bad for SEO as these are termed as soft 404s (https://support.google.com/webmasters/answer/2409443?ctx=MCE&ctx=S4&hl=en&authuser=1)

Steps to Reproduce (for bugs)


  1. Follow the example here https://github.com/zeit/next.js#reusing-the-built-in-error-page
  2. Look in the network request, you will see 200 instead of 404 when the api calls does not give a proper response.

Context

The problem is majorly because we are doing client side routing and conditionally rendering a 404 page for the users, however to a web crawler it still is a 200 page.
I am not sure how do I manually render a 404 page from server.js either.

Most helpful comment

How about I cache it like this?

const cachedRender = (req, res, pagePath, queryParams) => {
  const key = `${req.url}`

  if (!dev && ssrCache.has(key)) {
    res.append('X-Cache', 'HIT')
    res.status(ssrCache.get(key).statusCode)
    res.send(ssrCache.get(key).html)
    return
  }

  app
    .renderToHTML(req, res, pagePath, queryParams)
    .then(html => {
      ssrCache.set(key, {html: html, statusCode: res.statusCode})

      res.append('X-Cache', 'MISS')
      res.send(html)
    })
    .catch(err => {
      app.renderError(err, req, res, pagePath, queryParams)
    })
}

All 9 comments

You receive the res object in the getInitialProps of your custom error, there you can run res.statusCode = 404.

And it worked!!

Okay so it worked only on development build. If I build it for production, I get a 200 again instead of 404.

@harshmaur if you have a repo that I can clone and play with, I'll be happy to take a look since I'm doing this in my project and can return an Error page with 404 status

So I figured I am using ssrCache example with nextjs and my first render is 404 but next renders since it gets rendered through cache which returns a 200

Here is my ssr config.

const cachedRender = (req, res, pagePath, queryParams) => {
  const key = `${req.url}`

  if (!dev && ssrCache.has(key)) {
    res.append('X-Cache', 'HIT')
    res.send(ssrCache.get(key))
    return
  }

  app
    .renderToHTML(req, res, pagePath, queryParams)
    .then(html => {
      ssrCache.set(key, html)

      res.append('X-Cache', 'MISS')
      res.send(html)
    })
    .catch(err => {
      app.renderError(err, req, res, pagePath, queryParams)
    })
}

Alright, so that's your problem then. You need to cache status code too. I suppose you can cache it with middleware or a reverse proxy since it would be a lot easier

How about I cache it like this?

const cachedRender = (req, res, pagePath, queryParams) => {
  const key = `${req.url}`

  if (!dev && ssrCache.has(key)) {
    res.append('X-Cache', 'HIT')
    res.status(ssrCache.get(key).statusCode)
    res.send(ssrCache.get(key).html)
    return
  }

  app
    .renderToHTML(req, res, pagePath, queryParams)
    .then(html => {
      ssrCache.set(key, {html: html, statusCode: res.statusCode})

      res.append('X-Cache', 'MISS')
      res.send(html)
    })
    .catch(err => {
      app.renderError(err, req, res, pagePath, queryParams)
    })
}

The above seems to work.

@sergiodxa How do we set this up for default 404 page provided by Next.js?

Was this page helpful?
0 / 5 - 0 ratings