I have a collection in my CMS for localizations. It contains two fields; id and text.
Right now I’m fetching every single row and putting them into a Context, then children can use useTranslation and fetch the id they want. This worked fine when I only had a few rows, but now I need to rethink this approach. It’s not very effective to send every single localization to the frontend to be hydrated on every page load.
I thought about batching the requests, but I don’t think there’s a way for me to know which ids the server should provide to the Provider before render, and I don’t want to do it after page load and show a spinner for every piece of text.
I don’t think I can use a server component for a single localization either because you can’t put them in client components.
What I did was to use next-intl and separate my i18n strings into two separate files. One containing the strings required on the client and the other file containing strings referenced solely in server components. When setting up the i18n provider for the client I would then just pass on the client variables and thus have a much smaller footprint for those.
To help out with the setup I wrote a custom script to deduce which variables are used only on the server and which are used in client-side code, however that script is very specific to my project.
Not using components but conceptually with separate hooks, yes. The client-side useTranslations hook pretty much returns the values passed to the i18n context provider and works as you’d expect it. In server-side code I use getTranslations (specifically from next-intl) which does some magic under the hood using React’s cache function that gets initialized on request and allows you to obtain the same set of server-side variables anywhere in your component tree. It works a bit like a server-side context provider.
Another thing to keep in mind is to evaluate whether you really need to split the translations into separate bundles for lack of a better term. Try to measure the impact of i18n objectively to see whether it’s even necessary to optimize. In many cases, that won’t be the case and is typically premature optimization without any indication it’s required.