Is it possible to trigger a Netlify function on page 404?

I’m currently wrangling client side redirects, and finally have a solution that works, but it’s not great for SEO: a missing page still registers as a 404 before being redirected to the new page. (yes, I know the _redirects file is server-side and fixes this, but it can’t handle redirects from/to specific anchors)

I’m wondering if it would be possible to set up a Netlify function that fires whenever the server registers a 404, and intercepts the response. The function would:

  • Check if there was a redirect available
  • If yes: redirect with the correct code
  • If no: send the 404

I found this example, which works as far as it goes: netlify-functions-workshop/redirect.js at master · DavidWells/netlify-functions-workshop · GitHub

However, the info I’m missing is how to invoke the function, whenever a URL 404s (ideally with the 404ing URL as part of event or context parameters)

Hey @StarfallProjects

You could/can use a function to handle missing pages. As I believe the _redirects file (as per previous thread) is generated during project build you can add the following to the netlify.toml in the project root

[[redirects]]
  from = "/*"
  to = "/.netlify/functions/FUNCTION_NAME"
  status = 200

Then using that function as an example:

exports.handler = async (event, context) => {

  // Extract path e.g. /some/page
  const {
    path
  } = event;

  // Process the `path`

  // Redirect
  if (doRedirect) {
    return {
      statusCode: 302 // or 301,
      headers: {
        Location: redirectUrl,
        'Cache-Control': 'no-cache',
     },
    body: JSON.stringify({})
  }

  // Other conditions perhaps

  // Honestly, nothing found
  return {
    statusCode: 404,
    headers: {
      'Content-Type': "text/html"
    },
    body: `<!doctype html><html lang="en"><meta charset=utf-8><title>404 Not Found</title>`
  }
}

This will only work when site content is static (which thankfully VuePress is.)

If SSR is used (such as with SvelteKit) where it uses

* /.netlify/functions/render 200

or the site is an SPA (such as React or Vue) which needs the following rule for client-side routing to work (see docs)

/*   /index.html   200

the above function would never trigger.

The question then is, what is the function going to check against? It doesn’t have access to anything that is deployed, so you could need to either have all the data in the function or use an external source to check against.

1 Like

I believe one can workaround that. You can use Netlify API to fetch a file from your deploy and parse it in the function and check for the config in that. That’s what I’m using here:

2 Likes

@coelmay that will still hit the same problem though - can’t redirect from a #. Unless ALL page requests hit the function, which I assume would get expensive fast? It looks like in your example, everything goes through the redirect?

No, you can’t redirect from a #, because the # is handled by the browser as pointed out in your previous thread. The # would never make it to the function in the first place.

Not everything. Only paths that do not exist. If you added force = true, then eveything would.

This wouldn’t necessarily get expensive. Even the Starter Tier has 125k function invocations a month.

1 Like

Thanks for your patience and help!

You’re welcome.

Did find an issue on the Installation page (which I believe is unrelated) in that two clicks are needed for navigation to take place to a anchor.

n8n.io-nav