next-translate icon indicating copy to clipboard operation
next-translate copied to clipboard

Support overriding locale

Open Cyral opened this issue 3 years ago • 3 comments

Hello,

I'd like to set the locale based on a cookie rather than use the built in NextJS path detection. Meaning that every page will have regular routes like /, /login, /account, etc. (NO language routing like /de/login/)

I found that I can add (appContext.ctx.req as any).locale = locale; to my getInitialProps to override the locale to whatever I want (such as loading from a cookie). This works for the initial page load and any other pages which have getServerSideProps (for some reason), however it fails for other pages and reverts back to the default locale.

I am not very familiar with the code base, but I was able to track down the issue to this line: https://github.com/vinissimus/next-translate/blob/master/src/appWithI18n.tsx#L73

If ...ctx and ...config were switched, the context would override the config for subsequent pages. Currently, if we set ctx.locale from the client in getInitialProps, the ctx.locale is overwritten by the ...config. So ctx.locale = 'de' is overwritten by config.locale which is set to 'en'.

For now I found a workaround, setting window.i18nConfig.locale = locale works because of line 57 which makes that and the config the same object, but it feels pretty hacky.

Basically what I am doing is:

MyApp.getInitialProps = async (appContext: AppContext) => {
    const appProps = await App.getInitialProps(appContext);

 if (typeof window !== 'undefined') {
  window.i18nConfig.locale = <LOAD LOCALE FROM document.cookie ON CLIENT>
 }

   if (appContext.ctx.req) {
       (appContext.ctx.req as any).locale = <LOAD LOCALE FROM "cookie" HEADER ON SERVER>
   }

// Other server side props for app in here as well
 return appProps;
}

Cyral avatar May 03 '22 03:05 Cyral

How did you solve to use /, /login, /account for each language instead of /de/login/ ...? This is not directly supported (we are using Next.js i18n routing behind) so I imagine you also did a workaround to fix this, and maybe this causes you to have to make tradeoffs for the rest of the functionalities.

Currently, to use the cookie there is the NEXT_LOCALE cookie (supported in the Next.js core).

aralroca avatar May 03 '22 08:05 aralroca

Also if you want a better language detection way you can use this feature:

https://nextjs.org/docs/advanced-features/i18n-routing#prefixing-the-default-locale

aralroca avatar May 03 '22 08:05 aralroca

I just don't ever redirect the user to a /locale/ page. So the user never has /de/ because there are no links to it.

Cyral avatar May 03 '22 16:05 Cyral

To do that you can turn off the Webpack plugin and use the I18nProvider and manage the locale state by yourself.

i18n.js

module.exports = {
  ...restOfI18nConfig,
  loader: false
}

aralroca avatar Feb 20 '23 16:02 aralroca