-
Notifications
You must be signed in to change notification settings - Fork 280
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
Hydrogen i18n example #1279
base: main
Are you sure you want to change the base?
Hydrogen i18n example #1279
Conversation
// Configure the i18n locale format. e.g this will match /fr-CA/ or /en-CA | ||
export const subfolderLocaleParser = createSubfolderLocaleParser({ | ||
parser: ({COUNTRY, language, delimiter}) => | ||
`/${language}${delimiter['-']}${COUNTRY}`, |
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.
Would it be simpler to just make the parser be case insensitive? And the signature could also be {country, language, delimiter}
?
const {i18n, i18nSfApi} = await getI18n<typeof DEFAULT_I18N>({ | ||
cache, | ||
defaultI18n: DEFAULT_I18N, | ||
prefixParser: subfolderLocaleParser, |
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.
Not all i18n
will use URL prefixes, would this be better to be just named parser
?
isDefault: true, | ||
country: defaultCountry, | ||
language: defaultLanguage, | ||
prefix: subfolderLocaleParser({ |
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.
What would this be if i18n
was in the domain?
mode: process.env.NODE_ENV, | ||
getLoadContext: () => ({ | ||
cart, | ||
i18n, // Step 5. pass i18n to the Remix context |
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.
i18n, // Step 5. pass i18n to the Remix context | |
i18n, // Step 6. pass i18n to the Remix context |
// ... | ||
return defer({ | ||
// return i18n so that it is available throughout the app | ||
i18n: context.i18n, |
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.
Does this mean that the entire i18n
json for every route is sent down?
<Links /> | ||
</head> | ||
<body> | ||
<Layout {...data} key={`${i18n.language.code}-${i18n.country.code}`}> |
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.
Curious why the Layout has the key passed in like this?
// Step 3. use localized content for the account a login CTA's | ||
const loginLabel = isLoggedIn | ||
? t('layout.header.ctas.account') | ||
: t('layout.header.ctas.login'); |
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.
We talked about this before, but I'd like to start a discussion about somehow offering translation type safety.
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.
Have you considered using a library like react-i18next for the example? I think many people will want use advanced features that these kind of libs offer and type safety for the TFunction is really easy with it.
Co-authored-by: Dominik <[email protected]>
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.
Would it be possible to just make the JSON files available to existing i18n libraries instead of implementing our own t(...)
functionality? I think that's a huge rabbit hole with hidden features like pluralization etc. that we should avoid 🙈
It's definitely possible. I just did this for our project by combining the data fetching logic from this PR (getOxygenAssetsUrl etc) with react-i18next. Works like a charm so far. The readme of https://github.com/sergiodxa/remix-i18next gives a few pointers in their setup for what needs to be done, specifically |
@magnattic Can you share you're code? I am having trouble setting it up. |
It's in a private repo of one of my customers, so I can't share it directly. I could try to set up an example repo but that would take me some time which is in short supply right now. Maybe this PR is not the best place to discuss this, but if you let me know what's not working I could try to give you some pointers. |
@magnattic Where do you use getOxygenAssetsUrl (please show content of that file)? And how does your "i18next.server.ts" look with i18next-fetch-backend. If you could show that file it would definitely solve my problem. So the file "i18next.server.ts" would be very appreciated :) Would really appreciate just a very basic repo with the changes that made it working nothing else. If you send discord we can discuss it there instead :), then i can delete these messages in this PR. |
Hello, Would be great if we could have an exemple with i18next :) Thank you. |
Any update on this PR? An example on how to setup i18n would be very helpful. This PR looks like it rewrites a lot of i18n functionality which is a little strange. Curious to hear why. |
One thing I don't see addressed here is the support for plural translations. For example, in the cart I'd expect to see a text saying Depending on the language, you might also have 2+ different plural variants for Here there are a few examples on different cases of plural: https://www.i18next.com/translation-function/plurals Maybe here makes sense to use an external library to handle that? Otherwise it might be too much code rewriting inside Hydrogen itself. |
Hey, what is the status of i18n in Hydrogen? What is the recommended approach at this moment? |
I use metaobject (key, value) in shopify, so store owner can change the translations values and then just load them using @incontext language, create a react-hook const t = useCallback(
(key: string, options: Record<string, any> = {}) => {
const value = data[key];
if (!value) {
console.log(`missing_${key}`, data);
return `missing_${key}`;
}
return interpolateText(value, options);
},
[data, interpolateText],
); |
For detailed information on this PR please read the included RFC.md