amannn / next-intl

🌐 Internationalization (i18n) for Next.js
https://next-intl-docs.vercel.app
MIT License
2.31k stars 210 forks source link

Supported formatting APIs from `Intl` #774

Open amannn opened 8 months ago

amannn commented 8 months ago

Is your feature request related to a problem? Please describe.

We currently support a subset of formatting APIs from Intl:

Intl.DateTimeFormat

Intl.NumberFormat

Intl.ListFormat

Intl.RelativeTimeFormat

Intl.DurationFormat (not available yet in JS runtimes)

Describe the solution you'd like

There are valid use cases for every API, potentially we could support all.

For now, we'll add APIs as necessary and reported by users.

This will increase bundle size though, we should evaluate how much. Potentially we could also split useFormatter into separate hooks like const dateTimeFormat = useDateTimeFormatter(), const relativeTimeFormat = useRelativeTimeFormat(), const numberFormat = useNumberFormatter() (could be introduced alongside useFormatter for a longer transition period).

Also note that only a subset of these formatting APIs is supported by ICU.

Describe alternatives you've considered

Supporting only a subset, e.g. none of the ToParts variants and asking users to implement this in userland.

There are even more APIs from Intl (not necessarily related to formatting), so we'll likely not wrap every single API.

joaopbnogueira commented 3 months ago

Hi, I was doing a bundle analysis of a next 14.2.4 app with app router and I can see that intl-messageformat is automatically bundled for the client regardless of the need to actually use it. Not sure if it relates to this issue in particular, but would be nice to have it opt-in, e.g. as peerDependency instead of forced dependency.

Thanks!

amannn commented 3 months ago

Hey @joaopbnogueira, so you're not using useTranslations in any Client Components? There's a bit of tree shaking in place that helps when e.g. only navigation APIs are used in Client Components, that intl-messageformat isn't bundled. However, I believe if you use useFormatter, it will currently erroneously bundle intl-messageformat. I'm currently working on full ESM support in https://github.com/amannn/next-intl/pull/1115 to should fix this case (and others).

Which APIs from next-intl are you currently using in Client Components?

The longer-term solution is to get rid of intl-messageformat on the client side entirely, even if you use useTranslations (see https://github.com/amannn/next-intl/issues/962).

joaopbnogueira commented 3 months ago

Hi @amannn I am but I realize I'm working on a bit of a corner case scenario, where I am not using any of the intl-formatting/etc features (just plain text "resolution").

Anyways, for my purpose, using the null-loader for webpack and explicitly excluding intl-messageformat and @formatjs/intl-localematcher is working just fine. I get (some of) the niceties about next-intl in a SSG next app at a very low bundle size.

(In my case I do need useTranslations() on some client components, so having it server-only would be a bit of a hassle)

Cheers,

amannn commented 3 months ago

I see! @formatjs/intl-localematcher is btw. only used in the middleware, so I think you could keep that.

https://github.com/amannn/next-intl/issues/962 should be the proper solution to your use case to handle plain messages without overhead.