Gatsby routing issue for 404 pages with language keys

I am building a blog with multiple languages support. URLs contain language keys, e.g. /en/blog. I ran into an issue with localizing 404 pages. What's described here https://www.gatsbyjs.org/docs/creating-prefixed-404-pages-for-different-languages/ works well for all routes but the home page. The home page has the following URL www.test.com/en, and it ends up with 404 page because of this regex /^\/[a-z]{2}\/404\/$/ I tried to pass in a regex ^\/?[a-z]{2}\/.+ to match all routes but the /en one but the matchPath does not seem to except regex.

Pages are ranked under the hood; however, it seems that /en and /en/does-not-exist are treated the same, or the latter takes precedence over the former.

I wonder if someone faced this issue before and maybe there was a workaround.

For now, I have a generic 404 and also separate 404 pages for all available languages. In the generic 404, I want to redirect to the language-specific 404 version. It adds complexity which I'd like to avoid.

Any help appreciated. Thanks!

Upvotes: 2

Views: 1452

Answers (1)

Turns out this is a know everything in match-paths.json issue. https://github.com/gatsbyjs/gatsby/issues/19228

For now my workaround is using redirects based on language key.

I have a default 404 page and language specific 404 pages, e.g. /en/404. Inside the default 404 page I simply redirect lie so:

import { useEffect } from 'react';
import { navigate } from 'gatsby'

// Assuming the urls are structured this way /en/blog/does-not-exist
const getLanguage = (location) => location.pathname.split('/')[1]

const NotFoundPage = ({ location }) => {
  useEffect(() => {
    navigate(`/${getLanguage(location)}/404`, { replace: false })
  }, []);

  return null
}

export default NotFoundPage

Not the best solution but it does the job for now. Will post an update once I have a better solution.

Upvotes: 2

Related Questions