Implement translations support
- [x] Research how to store and fetch a specific content translation for markdown driven pages
- [ ] Implement fetching specific content translations for markdown driven pages
- [x] Research how to support routing to translations of a given page
- [x] Implement routing support
- [x] Research how to store and fetch a specific content translation for pages with layout expressed with React components
- [ ] Implement fetching specific content translations for pages with layout expressed with React components
- [x] Implement an enhanced link component which links to the appropriate language for a given page
- [ ] Review the features of react-intl and competing libraries and either make use of one of them fully, partially, or do not use at all
- [ ] Detect language preference; allow for toggling and maintaining user language preference
Since we have a number of tasks that need major spikes or deep dives into using new libraries, I had tentatively prioritized this task lower. I want to dive into this topic after finishing learning and applying the new libraries for other tasks.
I expect this task to consist of reviewing general concepts in internationalization, the various options for integrating React internationalization libraries with nextjs, and then proceeding to use one of the options.
Research how to store and fetch a specific content translation for markdown driven pages.
I wrote a very brief explanation of how to implement this in the document "Next.js Internationalization Solution Brief."
Research how to support routing to translations of a given page
If we are willing to accept being locked in to NextJS and Vercel or OCurrent (as opposed to Gatsby or another competitor) and if we are willing to use next as our production http server (as opposed to caddy, nginx, or any other competitor), then we might consider using NextJS's server side routing for internationalization. It sounds promising and since the server side won't have a persistent state such as a database, it won't introduce significant operations overhead. (Richard prompted me to reconsider my assumptions. I haven't formed an opinion yet.)
@rdavison has completed a large amount of the research for this task.
- Research how to support routing to translations of a given page
- Implement routing support
Most of this work may be covered by PR #438.
If we are willing to accept being locked in to NextJS and Vercel
We have a concrete request to not use nextjs as a production http server, now that docs.ocaml.org is exploring using next export to combine the output of the v3 site with the generated html from the docs project. (Alternatively, if use nextjs rewrites to forward requests for docs pages to an external http server, then nextjs could still be suitable as a production http server).
Implement an enhanced link component which links to the appropriate language for a given page
Done in #470.
The index page still isn't ideal, as it is currently forcing a redirect to the default page. I think something we can do to eliminate this behavior is to detect the default language, perhaps by reading the HTTP header, and then loading the correct content for the index page. All links pointing away from the index page can add the language to the URL.
I recently went through all of this for a website. Runtime solutions cost a moderate amount of JavaScript, suffer extra blocking downloads (language message pack), or have naive namespace splitting of the locale corpus.
my solution was to write a webpack loader to:
- at devtime, render messages using the developer requested locale
- At prod build time, split into two steps:
- where text or a text function is used, instead of providing the locale message of interest, inject that message from ALL locales, in some structured format
- copy the app that has all locales into a locale specific folder of interest (eg apps/en-US), then reduce the embedded message to just the locale of interest, stripping the other locales out of the assets.
- If you are doing static only builds, you may be able to do this much easier/less-complexity, and dodge this two step malarkey to get locale aware messages into the correct assests.
Benefits:
- no runtime overhead or complexity. Very simple—nearly like developing an app for a single language
- best possible performance for browsers
Challenges:
- build time complexity. extra processing, uncommon architecture
- lots of files? App artifacts are multiplied by N locales. Thus, cost on CDNs may be higher 🤷♀️
With NextJS, you can weave together different approaches to data splitting using getStaticPaths and getStaticProps. The current implementation combines generating OCaml modules holding locale content as a pre-build step with using getStaticPaths and getStaticProps to fetch locale content at build time.
Ah, nice! Ok, disregard my prior then :)
I think you would have found it very interesting to review the details of the two general approaches that were under consideration. It is probably documented in one of the discussions of the closed issues. Here is a quick recap:
- You can pass in all the translations into the React component, and then dispatch within the React component
- You can use getStaticProps to select the appropriate translation, and only forward that subset to the React component
The small downside of using getStaticProps is that you have to add some serialization boilerplate code to pass the data between getStaticProps and the React component. The upside of using getStaticProps is the ability to delegate data splitting to NextJS.
Review the features of react-intl and competing libraries and either make use of one of them fully, partially, or do not use at all
https://github.com/ocaml/v3.ocaml.org-server/pull/84 is moving closer to a classic react-intl approach to text elements that need translation, so react-intl might be a natural choice here to complement that direction.