-
Notifications
You must be signed in to change notification settings - Fork 3
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
Add support for internalization #7
Conversation
Huge challenge to support quickly the French, English and German translations. |
ddf3a29
to
c43b0f7
Compare
So I think this is mergeable as is. The idea is:
|
Updated CI to use "npm" instead of yarn for the frontend project based on @manuhabitela's recommendations. Also updated the dependencies-related CI steps that were previously missed.
Fixed a typo and ensured all instances of "crowdin" are capitalized for consistent naming.
c43b0f7
to
3a53523
Compare
Should we open an issue to keep in mind?
With a low priority tag |
src/frontend/package.json
Outdated
@@ -7,17 +7,24 @@ | |||
"dev": "panda codegen && vite", | |||
"build": "panda codegen && tsc -b && vite build", | |||
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", | |||
"preview": "vite preview" | |||
"preview": "vite preview", | |||
"i18n:extract": "i18next -c i18next-parser.config.json" |
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.
I am a bit lost and don't know which make commands run ... should we write a bit of documentation in /docs
it would be beneficial for all projects (Impress, Regie, etc..).
I would be more than happy to take this task
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.
you can use the i18n:extract
command (or make frontend-i18n-extract
) if you want to generate missing translation keys in the json files (it checks all t
calls in the react app). Handy while developing to make sure you didn't forget any new string to translate. But not actually necessary to use, you can also add your keys by hand while developing normally.
In the CI this is called to send translation keys to Crowdin.
"backToHome": "", | ||
"error": { | ||
"heading": "" | ||
}, | ||
"forbidden": { | ||
"heading": "" | ||
}, | ||
"app": "Meet", | ||
"login": "Anmelden", | ||
"logout": "", | ||
"languageSelector": { | ||
"popoverLabel": "", | ||
"buttonLabel": "" | ||
}, | ||
"loading": "", | ||
"notFound": { | ||
"heading": "" | ||
}, | ||
"homepage": { | ||
"heading": "", | ||
"intro": "", | ||
"createMeeting": "", | ||
"login": "", | ||
"or": "", | ||
"copyMeetingUrl": "" | ||
} |
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.
I am not sure what the best practices are for organizing translations. Any resource or tips to share?
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.
I guess there are multiple ways to see it:
- either have keys that are the actual text to translate. like
Error: page not found
, - either have keys that represent what we say. Like
pageNotFound
. - either have keys that represent in what context the string is used. Like
notFound.heading
- either have keys that are strictly tied to their use in the source code. Like
layouts.NotFoundScreen.heading
First option goes a bit against how i18next works as it's more meant to be used with actual keys. So just changing a typo in an existing "key" makes us having to update the key in all languages.
I feel second option could quickly become a bit hard to manage, if lots of translation strings at the root level, maybe.
Fourth option makes translations extremely tied to our component structure. If we happen to use a different component for the not found page, we also have to change the key translation everywhere.
That's why I went with the notFound.heading
style. It's a bit messier compared to fourth option I guess, but the fact our translations are not 1:1 match with components means the translations are more future proof.
And for now, all the "global" translation strings that are not really tied to a specific UI component are placed at the root of the global namespace.
We can figure this out as we go really!
Reading your PR I opened this issue #49 |
3a53523
to
94c0410
Compare
- dynamically load locale files for smaller footprint - have a namespace for each feature. At first I'd figured I'd put each namespace in its correct feature folder but it's kinda cumbersome to manage if we want to link that to i18n management services like crowdin…
the base path is actually not a secret so we'd rather have it outside secrets and see it easily
- upload local translation files on push - make crowdin create a pull request when new translations are made through the crowdin website (webhook configured on crowdin-end)
makes more sense i guess, maybe
94c0410
to
2598076
Compare
Purpose
Fix various issues related to i18n.
Proposition
i18n-crowdin
CI stepsfrontend-i18n-*
makefile commands