QuiiBz / next-international

Type-safe internationalization (i18n) for Next.js
https://next-international.vercel.app
MIT License
1.19k stars 52 forks source link

Reducing the size of locales that will be downloaded on page load by specifying namespaces #321

Open salmanorak opened 6 months ago

salmanorak commented 6 months ago

Hello @QuiiBz,

I have a proposal for one issue that has been mentioned in the issue #312.

I have also implemented a basic implementation with this PR.

The suggestion is to let users add namespaces that will be used for that specific page and let them reduce the downloaded locale size.

I have added 2 tests.

Please feel free to make comments on it. I just struggled with types a little bit. You may want to check them if You find the solution beneficial.

vercel[bot] commented 6 months ago

@salmanorak is attempting to deploy a commit to the Tom Team on Vercel.

A member of the Team first needs to authorize it.

salmanorak commented 6 months ago

Yes, it makes sense to have a common API and solution for both router options. Then maybe a common config on the project level can be used here to sync namespace requirements for server components, client components, and the Pages router.

i18nConfig : {
  pages: {
     '*' :  ['common','errors'], //namespaces that will be required for all pages can be represented like this.
     page1: [ 'ns1'],
     page2: ['ns2' ],
     page3: [ 'ns1', 'ns2.subnamespace' ], // subnamespaces can be used like this.
     page4/[:id] : [ns4]   // dynamic pages can be represented like this.
  }
}

Then this config can be used in the code to pick the correct set of localization keys. With this, the appropriate function that will implement this logic can be picked for each router and component type.

I think for the pages and router getLocaleProps function can be the correct point to implement the filter.

What do You think about this approach?

PS: Maybe we may need to add a rule that will let the user pick a namespace list for all pages that are under a specific path. For example, all pages under /dashboard path should have ['dashboard'] namespaces.

zakidze commented 5 months ago

this library does that
https://github.com/aralroca/next-translate this also https://github.com/i18next/next-i18next

splitting the dictionries would be soo huge

ouedyan commented 5 months ago

this library does that aralroca/next-translate this also i18next/next-i18next

splitting the dictionries would be soo huge

@zakidze i18next/next-i18next isn't compatible with the app router and RSC. aralroca/next-translate does it for both pages and app router but breaks SSG in the app router. See https://github.com/aralroca/next-translate/issues/1154 . What would be really huge is supporting it properly both in the pages and app router without breaking Next.js as @QuiiBz suggested.

salmanorak commented 5 months ago

I just want to share my thought about implementation suggestion.

We can create a page-namespace mapping configuration, that can be used by both Router options.

App Router

  1. Server Component: Server components May not need this optimisation, since file upload on the server May not push too much cost on the flow/system.

  2. Client Components: The download of dictionaries happening in the context provider by consuming the importedLocale promise. İf we directly use this promise, it will download all dictionaries that we are trying to avoid. Somehow on the server deduction operation should complete and client components should consume that filtered dictionaries. I am not sure but the function that will filter the dictionaries and return only required section could be a server action.

Pages Router

We can consume same page-namespace configuration and filter the dictionaries on the server Side before they have been passed to client. The candidate location can be getLocaleProps or any step that is completed on the server.

QuiiBz commented 5 months ago

Thanks for sharing your thoughts @salmanorak. Completely agree with what you've said: