Search code examples
reactjsnext.jsinternationalizationnext-intl

Why next-intl does not provide a way how to define default messages directly in components?


Why does next-intl (and some other react translation tools) NOT provide a way how to define default messages directly inside components?

For example:

next-intl is used like this:

/* obtain the t from some hook etc. */
const content = (
  <>
    <h1>{t('title')}</h1>
    <p>{t('text')}</p>
  </>
);

while react-intl:

/* import FormattedMessage from react-intl */
const content = (
  <>
    <h1><FormattedMessage id="title" defaultMessage="Hi there!" /></h1>
    <p><FormattedMessage id="text" defaultMessage="Since when is developing frontend such a pain?" /></p>
  </>
);

What is the reason for not having the default messages defined directly inside of componets? Is it the bundle size? If so, is there some tool that could remove the default messages from the production builds?

Adding the new keys and messages to the related jsons manually feels like a huge step back to me.

Thank you for clarification.


Solution

  • Not an author of the package but to me it makes sense.

    Providing a default message would mean the string is always sent to the user unless you use some workaround as you said.

    The way that package works if you have all the strings localized you can send only the localized strings and nothing else. So it is bundle size related.

    Note you can still load default locale like this:

    import { getMessages } from "next-intl/server";
    import { NextIntlClientProvider } from "next-intl";
    import deepmerge from "deepmerge";
    
    const userMessages = await getMessages();
    const defaultMessages = await getMessages({ locale: "en" });
    const messages = deepmerge(defaultMessages, userMessages);
          
    <NextIntlClientProvider messages={messages}>{...}</NextIntlClientProvider>