-
Notifications
You must be signed in to change notification settings - Fork 3
Add i18next integration #242
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Install i18next and react-i18next with full SSR support - Configure client-side i18n with browser language detection - Configure server-side i18n with filesystem backend - Add improved German translations (idiomatic business German) - Integrate with Vite via i18next-loader plugin - Add i18next middleware to Express server - Update server-side entry to serialize translations for hydration - Update client-side entry to hydrate with server state - Translate all Welcome page content with defaultValue pattern - Document i18n usage and architecture in CLAUDE.md English text stays inline in components as defaultValue. Other languages defined in src/locales/*.json files. Browser automatically detects user's preferred language. No language flicker due to proper SSR hydration.
|
All contributors have signed the DCO. |
ebabe0d to
8894c30
Compare
|
I have read the DCO document and I hereby sign the DCO. |
| import i18n from './i18n.client.js'; | ||
|
|
||
| // Hydrate i18n with server state to prevent flicker | ||
| const { initialI18nStore, initialLanguage } = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without this we get "Willkommen" -> "Welcome" -> "Willkommen" because server first gets the language from the headers, returns German, then the client side is initializing its json language file and because this is async it shows English for a split second and this causes flicker. Happy to do it in a more elegant way but this is what Bob suggested after a lot of back and forth 😄
| supportedLngs: ['en', 'de'], | ||
|
|
||
| // Important for SSR | ||
| useSuspense: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ReactDOMServer does not yet support Suspense
| preload: ['en', 'de'], // Preload all languages on server | ||
|
|
||
| // Important for SSR | ||
| useSuspense: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ReactDOMServer does not yet support Suspense
…to server side response
| }; | ||
|
|
||
| const head = `<meta name="description" content="Server-side rendered page"> | ||
| <script>window.__INITIAL_I18N_STATE__ = ${JSON.stringify(initialState).replace(/</g, '\\u003c')}</script>`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this even the very first response from the server will contain the correct language that was sent in the request headers.
| // https://vite.dev/config/ | ||
| export default defineConfig({ | ||
| plugins: [react()], | ||
| plugins: [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can also be loaded via native json file loaders but this one seemed reasonable to use https://www.npmjs.com/package/vite-plugin-i18next-loader
Summary
t('someKey', "Default value in English co-located like this")