Gatsby V4: How to implement gatsby-plugin-react-i18next for client only routes

1k Views Asked by At

I'm trying to implement client routes in Gatsby together with gatsby-plugin-react-i18next for two languages. I followed officel Gataby documentation and there is no client only path implementation explained.

Below is the code i implemeted.

gatsby-node.js
   function langPrefix(page) {
      return page.context.language === page.context.i18n.defaultLanguage &&
        !page.context.i18n.generateDefaultLanguagePage
        ? ''
        : `/${page.context.language}`
    }
    
    
    
    exports.onCreatePage = ({ page, actions }) => {
      const { createPage } = actions
      // Removing the ^ skips an optional /:lang prefix
      if (page.path.match(/\/app/)) {
        // adding lang if it's not the default page.
        page.matchPath = `${langPrefix(page)}/app/*`
        createPage(page)
      }
    }

Appjs

 src/app/app.js
    function App() {
      return (
        <>
          <Router basepath="/:lang/app">
            <PrivateRoute path="/accounthome" component={AccountHome} location=""/>
          </Router>
          <Router basepath="/app">
            <PrivateRoute path="/accounthome" component={AccountHome} location=""/>
          </Router>
        </>)
    }
    export default App

Gatsby config

{
      resolve: `gatsby-plugin-react-i18next`,
      options: {
        localeJsonSourceName: `locale`, // name given to `gatsby-source-filesystem` plugin.
        languages: ["en", "fr"],
        defaultLanguage: `en-us`,
        fallbackLanguage: `en-us`, 
        // if you are using Helmet, you must include siteUrl, and make sure you add http:https
        siteUrl: `https://my.costco.com/`,
        ns: langTranslationConfig,
        // you can pass any i18next options
        i18nextOptions: {
          interpolation: {
            escapeValue: false // not needed for react as it escapes by default
          },
          nsSeparator: false
        }, 
        pages: [
          {
            matchPath: '/:lang/app/accounthome',
            getLanguageFromPath: true,
            excludeLanguages: ['en-ca']
          },
          {
            matchPath: '/preview',
            languages: ['en']
          }
        ]
      }
    }

Router path : http://localhost:8000/en-us/app/accounthome When am accessing this rote in browser This code show Gatsby.js development 404 page not found. Any pointer what am missing and am not sure how to access the translation contents in client only route page example account home page. Do i need to write the graph query in account home page or i dont need to ?

1

There are 1 best solutions below

3
Ferran Buireu On

I think your regex is leaking your code. I guess it should look like:

  if (page.path.match(/^\/app/)) {
    page.matchPath = `${langPrefix(page)}/app/*`
    createPage(page)
  }

Either way, check the created page list by accessing the 404 page in development mode. By default, there should be a list of all created pages. Check the paths there to see if you can spot any mistakes or trailing slash issues.

The problem here is that your page is not being generated properly, that's why it throws a 404, so checking the created pages may help you to spot the mistake or at least, a thread to pull.

After a few research I've seen that you are basing your approach in: Gatsby can't find client routes when using gatsby-plugin-react-i18next

In their case, the langPrefix function is only prefixing the language to the page slug if it's the default one:

function langPrefix(page) {
  return page.context.language === page.context.i18n.defaultLanguage &&
    !page.context.i18n.generateDefaultLanguagePage
    ? ''
    : `/${page.context.language}`
}

In your case, I'm not sure the plugin supports en-us (it's en-US according to https://github.com/microapps/gatsby-plugin-react-i18next/issues/100) and I think that's the reason why there's a leak in your page creation. Try using en instead of en-us or directly looking for en-US paths.