alibaba / react-intl-universal

Internationalize React apps. Not only for Component but also for Vanilla JS.
1.33k stars 153 forks source link

Nextjs: Overusing intl.init() function #241

Closed NaifAlqahtani closed 8 months ago

NaifAlqahtani commented 9 months ago
const ar = {
  "light": "فاتح",
  "dark": "داكن",
  "system": "النظام",
}

const en = {
  "light": "Light",
  "dark": "Dark",
  "system": "System",
}

const locales = {
  "/en": en,
  "/ar": ar
}

export function ModeToggle() {
  const { setTheme } = useTheme()
  const path = usePathname()
  intl.init({ locales, currentLocale: path })

  return (
    <DropdownMenu>.... </DropdownMenu>
   )
}

Due to the nature of having to do server-side rendering and client components etc... I resorted to the above method of defining the locale translations as a javascript object in the definition of each react component and server page. This means I need to call intl.init on each component/page and pass to it the local locale for that individule page/component (Hopefully to save performance?)

On nextjs app directory, with pages being rendered in other pages etc... I found that once I change the locale, the outer most page elements are updated but the inner page (nested page) does not. I need to perform a refresh on the browser for it to update (command + R on chrome). However, adding intl.init inside the nested page solved this issue.

splitting locale like this has its benefits and drawbacks, mainly that it is convenient to store text and component functionality in the same file with the cost of lots of refactoring if I ever intend to support more languages (which I don't see myself planning for at all)

The question

Does calling intl.init everywhere have side effects that I am not aware of where I might run into issues in the future? I currently implemented it this way and all seems fine. However, I am hesitant to continue building with the idea that I might run into issues (performance related, SEO related, or otherwise).

Any help? Thanks!

cwtuan commented 9 months ago

To support multiple languages, create separate intl instances for each language.

const enUSIntl = new ReactIntlUniversal();
const zhCNIntl = new ReactIntlUniversal();
enUSIntl.init({ locales : {...} , currentLocale: "en-US"});
zhCNIntl.init({ locales : {...} , currentLocale: "zh-CN"});

Use the appropriate intl instance to render pages in different languages.

NaifAlqahtani commented 9 months ago

Thanks for the reply!

I am not concerned with supporting multiple languages.

I am more concerned with performance issues of calling the .init() function across ALL components and pages and routes.

Will that affect anything? Or is it okay? In terms of performance of course.

cwtuan commented 9 months ago

You should only init once at server starts

NaifAlqahtani commented 9 months ago

I see.

However, as I stated above, for some reason with Nextjs’s nested pages in app directory as well as server and client side components being rendered separately, it causes a lot of errors in loading locale files.

My question is, what are the implications and repercussions of calling init function over all components and pages?

Get Outlook for iOShttps://aka.ms/o0ukef


From: cwtuan @.> Sent: Saturday, November 18, 2023 3:41:26 PM To: alibaba/react-intl-universal @.> Cc: Naif Alqahtani @.>; Author @.> Subject: Re: [alibaba/react-intl-universal] Nextjs: Overusing intl.init() function (Issue #241)

You should only init once at server starts

— Reply to this email directly, view it on GitHubhttps://github.com/alibaba/react-intl-universal/issues/241#issuecomment-1817498740, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AMD55LSYQOV4TXWPWDODAPDYFCUHNAVCNFSM6AAAAAA7NYBBMWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMJXGQ4TQNZUGA. You are receiving this because you authored the thread.Message ID: @.***>

cwtuan commented 9 months ago

There is no problem when you call init multiple times. It's just replace the whole locale data object in react-intl-universal.