-
-
Notifications
You must be signed in to change notification settings - Fork 236
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
Fully serializable config #611
Comments
Note this doesn't handle the case where I want to pass the messages as an object from another component. I.e. const MyComponent = ({ translationValues }) => t.rich('translationKey', translatioNValues); So IMHO the whole RichTranslations and MarkupTranslations should support non-functions. |
You mean when |
Wdym by that? I should be able to pass translation values as props between any component if I wish. Shouldnt be blocked by an implementation detail of making them a function. In other words, what if I have dynamic values and want to map them, I'd be unable due to next-intl requiring markup or rich text to be wrapped on functions... |
React defines the rules for which props are serializable.
t.rich('hint', {
help: (chunks) => <Link href="/help">{chunks}</Link>
}) Theoretically, React elements themselves are serializable, so from an API perspective the value of t.rich('hint', {
help: <Link href="/help" />
}) However, if the element that is passed to Long story short, I can't think of an API that has the same flexibility as the current My comment on top of this thread describes examples for sharing common rich text elements. I think it's helpful to discuss this based on concrete examples to be able to find good solutions. In case you can think of a better pattern, let me know! |
I think sharing this with you is self-explanatory. Pretty much there's a translation key that we want to have a specific part of it to be surrounded with a "span" element (https://github.com/nodejs/nodejs.org/blob/main/i18n/locales/en.json#L84), that's it. This was possible before, because react-intl allowed me to replace a variable, such as I understand that this is unrelated to next-intl, and react-intl would face the same issues once I've used server components; Hence me indulging if it makes sense to support something else. In the end, I just want to be able to share translation values from Component A to Component B. Right not it works because both components are client components, but I feel that maybe next-intl should support a way to transfer rich-text content independent if the component is RSC or CSC... 🤔 Not a big deal, but I feel that it'd be nice if it was supported. Either by something like: const translationContext: RichTranslationValues = {
graySpan: '<span className="small color-lightgray">{0}</span>'
} Encapsulating the HTML code within a string and then eval'ing it. And the translation key be like: "apiLts": "{fullLtsNodeVersion} API <graySpan>something</graySpan>", I know this is just a poor example, and definitely a stretch. |
Also sorry if I'm just crying wolf here, @amannn, please feel more than free to just disregard my request! |
That's an interesting one, because you didn't need chunks previously (since "LTS" was hardcoded):
There's currently an expandable section in the rich text docs about self-closing tags. This could be updated accordingly as part of this change. In regard to rich text content with chunks: I don't see eval'ing as a good direction here, to be honest. The provided elements can not just be HTML, but any React component. To come back to your example: I think there could also be a question here about which parts of the component should be Server or Client Components. Briefly looking into the code, I'm wondering if the rendering of the sidebar could be achieved in RSC and only individual items that need to be highlighted if they're active could be Client Components. The next-intl App Router example does just that for the navigation. If you're staying within RSC for the rendering of the items, then this problem also disappears. Hope this helps! |
Hm, true, I think I can make it RSC compatible.
Right, I'm also not a fan of this. But I believe at least for the case you mentioned above about without chunks, worth documenting it and updating the types. Can be useful for some folks :) |
Yep, I agree! |
Aaand, found a way to make it RSC by removing the only Hook that was "client-dependent" |
Awesome! 👏 |
I've added #1285 to investigate a better way to achieve global error handling. |
`defaultTranslationValues` allow to share global values to be used in messages across your app. The most common case are shared rich text elements (e.g. `b: (chunks) => <b>{chunks}</b>`). However, over time this feature has shown drawbacks: 1. We can't serialize them automatically across the RSC boundary (see #611) 2. They get in the way of type-safe arguments (see #410) Due to this, the feature will be deprecated and the docs will suggest a better alternative for common tags in rich text that doesn't have the limitations mentioned above ([updated docs](https://next-intl-docs-git-feat-deprecate-defaulttrans-f52ebe-next-intl.vercel.app/docs/usage/messages#rich-text-reuse-tags)). Shared values don't get a direct replacement from `next-intl`, but should be handled as part of your app logic (e.g. a shared module, React Context, etc.). **Note**: #410 can not be implemented immediately as part of this, as long as `defaultTranslationValues` are still available (even if deprecated). Instead, this feature could be added as part of the next major release. Contributes to #611
Due to this, I'll close this issue. |
Is your feature request related to a problem? Please describe.
These three config options accept functions and can therefore not be serialized currently:
defaultTranslationValues
onError
getMessageFallback
Due to this, we can't automatically pass them from an RSC render to the client side.
It might be worth investigating serializable alternatives, to avoid this.
Describe the solution you'd like
defaultTranslationValues
Maybe a better option could be to deprecate the option altogether and ask users to share values e.g. via a component:
… or imports:
As a nice side effect, this would allow us to statically type the arguments of a given ICU string (see #410), since there are no potential global values floating around.
Another benefit could be to remove ambiguity between values that should be used for
t.rich
andt.markup
(see #1181).onError
See #1285
getMessageFallback
See #1285
Alternatives:
MISSING: {namespace}.{key}
?Describe alternatives you've considered
NextIntlClientProvider
can be added in a client-side module graph to configure the non-serializable config options, see the docs.The text was updated successfully, but these errors were encountered: