Intercept response and return status code for Gatsby v3 pages

Viewed 309

I would like to intercept the response in Gatsby v3 from a page and return 404 based on some conditions while having the same page html content generated by Gatsby.

In practice, lets say that I have

src/pages/profile.js

and some client routes that are attached to it. For example, profile/:userId/:blogId, for example. If the userId or profileId do not exists, the page html should be returned with status code 404 but same content generated by gatsby.

Now, I tried looking into gatsby functions but that feature is not created for that purpose. Also, I looked into gatsby SSR and that feature is also not created for that purpose, at least as far as I researched.

Also, found this bug report in gatsby, but the last comment says its solved in some other ticket but the other ticket is about DEV_SSR, and does not talk about intercepting the response. When targeting a route with DEV_SSR === true, page-data.json does have a 404 status code but the actual html page (the first request sent to the server) is 200.

EDIT:

So to clarify, as far as I understand, the html page exists, and it is there but needs to be returned with status code 404. That is also true for the default 404.html that comes with Gatsby installed. Even if that default 404 page is rendered, it is returned with status 200, not 404, but the content is something like "404, page does not exist".

1 Answers

404 page should be handled automatically if the page doesn't exist (in your case userId or blogId), even in client-only routes.

However, if you want a more manual approach, handled by you, you can use onRouteUpdate API, from the gatsby-browser.js:

exports.onRouteUpdate = ({ location, prevLocation }) => {
  console.log('new pathname', location.pathname)
  console.log('old pathname', prevLocation ? prevLocation.pathname : null)
}

For SSR redirections you may find insightful this article: https://nesin.io/blog/redirect-in-gatsby-without-plugin

Given the following:

No, the actual html page generated by gatsby in src/pages/profile.js (for example), exists but given some condition, I would like to override default gatsby functionallity that returns 200, and return 404. But the actual page exists. But event if the page/route does not exist, gatsby returns 200 for the 404.html

Keep in mind that all that Gatsby intercepts in a page (src/pages/profile.js for example) using React will be handled by the browser, so it will return a 200 always, even if you made a to a 404 page, the 404 page will always exist so it will always return a 200 response to that page.

If you want to avoid that behavior, you need to make server-side rules (or using .htaccess), let's say if you want to make a redirect (301) from /whatever to /404, the 404 will still return a 200, because it exists. It's the /whatever that will change their status according to the server-side rules.

You can also use createRedirect action, from createPages, it allows you to set the statusCode but this integration will rely on how you are setting the pages.

// Generally you create redirects while creating pages.
exports.createPages = ({ graphql, actions }) => {
  const { createRedirect } = actions
  createRedirect({ fromPath: '/old-url', toPath: '/new-url', isPermanent: true })
  createRedirect({ fromPath: '/url', toPath: '/zn-CH/url', Language: 'zn' })
  createRedirect({ fromPath: '/not_so-pretty_url', toPath: '/pretty/url', statusCode: 200 })
  // Create pages here
}
Related