GithubHelp home page GithubHelp logo

amannn / next-intl Goto Github PK

View Code? Open in Web Editor NEW
1.8K 8.0 163.0 106.74 MB

Internationalization (i18n) for Next.js that gets out of your way. 🌐

Home Page: https://next-intl-docs.vercel.app

License: MIT License

TypeScript 98.79% JavaScript 1.21%
react next i18n date-formatting

next-intl's Introduction

Internationalization (i18n) for Next.js that gets out of your way.


πŸ“£ Support for the App Router and Server Components has arrived β†’


Features

Internationalization (i18n) is an essential part of the user experience, therefore next-intl gives you all the parts you need to get language nuances right.

  • 🌟 ICU message syntax: Localize your messages with interpolation, cardinal & ordinal plurals, enum-based label selection and rich text.
  • πŸ“… Dates, times & numbers: Apply appropriate formatting without worrying about server/client differences like time zones.
  • βœ… Type-safe: Speed up development with autocompletion for message keys and catch typos early with compile-time checks.
  • πŸ’‘ Hooks-based API: Learn a single API that can be used across your code base to turn translations into plain strings or rich text.
  • πŸš€ Next.js-native and performance-obsessed: App Router, Server Components, static renderingβ€”pick the right tool for the right job, next-intl works everywhere.
  • βš”οΈ Internationalized routing: Provide unique pathnames per language and optionally localize pathnames for search engine optimization.

What does it look like?

// UserProfile.tsx
import {useTranslations} from 'next-intl';
 
export default function UserProfile({user}) {
  const t = useTranslations('UserProfile');
 
  return (
    <section>
      <h1>{t('title', {firstName: user.firstName})}</h1>
      <p>{t('membership', {memberSince: user.memberSince})}</p>
      <p>{t('followers', {count: user.numFollowers})}</p>
    </section>
  );
}
// en.json
{
  "UserProfile": {
    "title": "{username}'s profile",
    "membership": "Member since {memberSince, date, short}",
    "followers": "{count, plural, ↡
                    =0 {No followers yet} ↡
                    =1 {One follower} ↡
                    other {# followers} ↡
                  }"
  }
}
Crowdin logo

Hosted on Vercel

next-intl's People

Contributors

ahmedbaset avatar albertothedev avatar amannn avatar apriltaoyvr avatar arochniak avatar awkaiser-tr avatar boris-arkenaar avatar codyduff avatar dacaramo avatar fcasibu avatar fkapsahili avatar flixlix avatar grzegorzpokorski avatar hhongseungwoo avatar iza-w avatar jajargaming avatar janoschherrmann avatar karimshalapy avatar louiscuvelier avatar majdi avatar martinmunillas avatar michalmoravik avatar mismosmi avatar oberwaditzer avatar outloudvi avatar polvallverdu avatar ravanscafi avatar romaingueffier avatar stefanprobst avatar tacomanator avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

next-intl's Issues

Automatic tree-shaking of messages

Messages can either be consumed in Server- or Client Components.

The former is recommended in the docs, as it has both performance benefits as well as a simpler model in general since there is only a single environment where code executes. However, for highly interactive apps, using messages on the client side is totally fine too. The situation gets a bit hairy when you need to split messages based on usage in Client Components (e.g. by page, or a mix of RSC / RCC).

Ideally, we'd provide more help with handing off translations to Client Components.

Ideas:

  1. User-defined namespaces
  2. Manually composed namespaces
  3. Compiler-based approach

(1) User-defined namespaces

This is already possible (and shown in the docs), but unfortunately not so maintainable. For single components it can be fine however, so when you have many small interactive leaf components, this is quite ok.

(2) Manually composed namespaces

This worked well for the Pages Router and was documented, but unfortunately doesn't work with RSC.

Apollo has a similar situation with static fragments: apollographql/apollo-client-nextjs#27

Since namespaces are only known in Client Components, they should be able to initiate the splitting, but they mustn't have received all possible messages at this point.

This can probably be realized if you expose an endpoint where translations can be fetched from. I've experimented with using Server Actions, but they can't be used during the initial server render in Client Components.

(3) Compiler-based approach

See #1 (comment). Similar to fragment hoisting in Relay, if the collection of namespaces happens at build time, we could provide this list to Server Components. This seems to be the best option.

Current progress:

How to handle date?

I can't figure out how to handle time. I've been using "javascript-time-ago" to display messages based off a timestamp. Like "1h ago" or "in 2hours".

But I'm sure I can deprecate this module and only use next-intl right?

Support for returnObjects

Current Behaviour
At the moment trying to resolve a key which has an array as its value throws a MISSING_MESSAGE (plus INSUFFICIENT_PATH) error.

Feature Requested
Support for returnObjects: true. At its most basic level, arrays, but will be great if it can support objects too. If the message bundle has --

{
  "items": [
    "item1",
    "item2"
  ]
}

then it should be possible to retrieve the list of translations for the key

const t = useTranslations('bundle');
const items = t('items',  { returnObjects: true });
// => [ "item1", "item2" ]

This feature is provided currently by next-i18next, next-translate etc., but next-intl seems to be much easier to setup and use. Something like this would be very handy for large scale applications like ours.

Revamped error handling

As mentioned by @ilanbm in #6 currently we throw for missing messages.

After some research I can think of two use cases where you want to keep the app running even if messages are missing:

  1. You don't have the messages yet. They'll be provided by a translator later on and you'd like to have a functioning app during development. However a warning would be helpful here.
  2. During unit tests you might want to assert for message ids to avoid hardcoding labels.

In both occasions it would be good to print the error by default, but opting out might be helpful.

What we could do, is to add an optional onError property on the provider which will allow the user to decide if and how errors should be handled. This can for example be used to turn off warnings about missing messages in unit tests.

I think errors should have the following properties:

  • code: An identifier that the user can detect.
  • message: A human readable message. This is only provided during development to reduce bundle size in production.
  • level: An enum with ERROR or WARN keys but which correspond to integers to be able to do checks like error.level >= NextIntlErrorCode.WARN.

Generally I can think of three categories of errors currently:

  1. Configuration issues which will break the app (e.g. missing NextIntlProvider). This is an ERROR, but we can't use a user-defined onError in this particular example, as there's no provider.
  2. Formatting errors which the developer has to fix (e.g. a missing value of a message). These use the WARN level, as we can render the message instead.
  3. Missing messages which need a translator to fix. These use the WARN level and render the ID instead, as the developer might not be able to fix it.

The default onError handler should throw an error for ERROR and print a console error for WARN (only in development).

TODO:

  • Log missing messages errors to console instead of throwing.
  • Introduce structured error instances and configurable onError prop to cover useTranslations.
  • Decide about an API to customize what is returned when a message is missing (e.g. <NextIntlProvider getMessageFallback={({path, error, message}) => ''} />)
  • Decide if we want to add error handling to useIntl functions as well. These should typically only be triggered by missing APIs (due to missing polyfills) or if the native APIs are used in an invalid way. Maybe it's ok to simply use the native error handling here as it's the developers job to fix it and there's e.g. no translator necessary.

useTranslations has {} as return type

currently tinkering around with all the different i18n solutions out there and stumbled upon this one.

for me useTranslations.d.ts sets the type as follows:

export default function useTranslations(namespace?: string): (key: string, values?: Record<string, string | number | boolean | Date | ((children: ReactNode) => ReactNode) | null | undefined> | undefined, formats?: Partial<Formats> | undefined) => {};

while clearly afaik this should return a string, doesn't it?

passing locale through NextIntlProvider

Hey guys
I'm using next-intl for integrating multi langs in my site but i faced a little issue which is having the locale from the route
because i need it to determine what language i want to show

this is my data type { "home": { "ar": "Ψ§Ω„Ψ±Ψ¦ΩŠΨ³ΩŠΨ©", "en": "Home" }, "donate": { "ar": "ΨͺΨ¨Ψ±ΨΉ", "en": "donate" } }

as you see u have [en - ar] inside the object
so how im solving this is in every compenent i want to show translation i import the t method useTranslations and locale from useRouter like so

`const t = useTranslations();
const { locale } = useRouter();

return (

  <h5 className="mt-1 mb-0">{t(`home.${locale}`)}</h5>

)

`

so i dont want to import locale on every component that i want to translate so is there any way i can extract the locale from the
NextIntlProvider ??

Iteration key with rich text

Describe the bug

When using t.rich for rendering rich text, and inside translation there is more than one occurrence of same element with same amount of element children or same string content, a React warning concerning repeated keys with weird key is shown in console.

image

To Reproduce

Any attempt, like

// Anything = '<b>first</b> lorem ipsum <b>first</b>'

return (
  <div>
    {t.rich('Anything', { bold: text => <b>{text}</b> })}
  </div>
)

Documentation update suggestion

on the documentation for time-zones you have t('ordered', {orderDate: parseISO('2020-11-20T10:36:01.516Z')});

But there's no reference to where that parseISO comes from. I'm suspecting its from date-fns. Could we use the equivalent in plain javascript? Date.parse() instead?

Benchmarking & performance optimisation

We currently cache the result of parsed messages. Is this sufficient or should we do more caching or memoizing? We already have fast-memoize bundled, so we could look into using that more.

But first see if this is really necessary or if the current performance characteristics are sufficient.

Type safe message access

Describe the solution you'd like
I would find it very helpful if message access was type safe, for example:

given messages like this:

# messages/en.json

{
  "Components": {
    "Greeting": {
      "body": "hello, world!"
    }
  }
}

it would be good to have typescript fail on these two examples:

const t = useTranslations("Components.Foo")
const t = useTranslations("Components.Greeting")
t("bar")

Additional context
I appreciate this could be hard for splitting message sets across different pages (as you may not know which message set is available at any given time) so having all return types be possibly undefined could be a compromise. The aim of the feature is not so much to guarantee access safety but to facilitate auto completion of keys to avoid typos etc.

Improve ability to load messages on the client side, automatic tree-shaking of messages & lazy loading

(repurposed from an older issue that was solely about lazy loading)

Messages can either be consumed in Server- or Client Components.

The former is recommended in the docs, as it has both performance benefits as well as a simpler model in general since there is only a single environment where code executes. However, for highly interactive apps, using messages on the client side is totally fine too. The situation gets a bit hairy when you need to split messages based on usage in Client Components (e.g. by page, or a mix of RSC / RCC).

Ideally, we'd provide more help with handing off translations to Client Components.

Ideas:

  1. User-defined namespaces
  2. Manually composed namespaces
  3. Compiler-based approach

(1) User-defined namespaces

This is already possible (and shown in the docs), but unfortunately not so maintainable. For single components it can be fine however, so when you have many small interactive leaf components, this is quite ok.

(2) Manually composed namespaces

This worked well for the Pages Router and was documented, but unfortunately doesn't work with RSC.

Apollo has a similar situation with static fragments: apollographql/apollo-client-nextjs#27

Since namespaces are only known in Client Components, they should be able to initiate the splitting, but they mustn't have received all possible messages at this point.

This can probably be realized if you expose an endpoint where translations can be fetched from. I've experimented with using Server Actions, but they can't be used during the initial server render in Client Components. SSR would be required though.

(3) Compiler-based approach

This is explored in #1 (see #1 (comment)). Similar to Relay, if the collection of namespaces happens at build time, we could provide this list to Server Components. The experimentation here hasn't progressed far yet, this is a bit further in the future.


This situation shows again, that staying in RSC will always be the simplest option. So if that's a choice for your app it's, certainly the best option.

Port for Remix?

I really like this library, we've used it with great success in our next.js apps. I've been very interested in using Remix lately, and was wondering how difficult it would be to port this simple, elegant solution over to support Remix as well. Have you done anything with Remix yet at all @amannn??

Help with implementing next-intl in a project with typescript

Hello @amannn. Good morning!

First of all, thanks for your wonderful package.

Well, I'm newbie in typescript and I'm facing some VS Code warnings when I use the "t" function. The parameter shows a underline and the following message:

Argument of type 'string' is not assignable to parameter of type 'never'

image

I know that is not a bug, but I don't know how to deal with this.

I will appreciate your help, if you can.

And thank you so much for your understanding.

Documentation improvements

  • Make sure all used functions are imported in the code samples (focus on copy-pasting)
  • Add a table of contents for quick scanning
  • A standalone website
  • Potentially a separate example that shows just the basic hello world setup and another one showing more advanced features
  • Live examples
  • Clarify which polyfills are needed and under which conditions
  • Seems like use new Date(dateString) is fine now in modern browsers, the docs should relfect that
  • Link to / use https://www.intl-explorer.com/DateTimeFormat?locale=en-GB?
  • Use TypeScript everywhere
  • Clarify what locale is
  • Upgrade code sandboxes.
  • Inline examples with sandpack?
  • Consider more examples or linking more to examples from the docs.
  • Avoid external links if not really necessary

Publish version of use-intl

Describe the bug
The latest version used by next-intl isn't published but is available in git

To Reproduce
yarn add next-intl asks for a version of use-intl because the one used in next-intl isn't available

Question: Multiple 'useTranslations' calls in the same component

I have been evaluating a few intl libraries for my nextjs based project. I just came across next-intl and thus far it looks great. I especially like that it follows certain intl standard(the ICU format for example) and also the fact that it is partially based off the robust formatjs library. Loading only relevant translations for the page and locale is a cool feature and something i was looking forward to.

Before i can finalise on the messages structure i had a couple of basic doubts: will having multiple useTranslations hook calls with the same component have any negative bearing on performance? If not, can it be considered an anti-pattern or is it perfectly ok to go ahead? In the repo example each relevant component has only a single useTranslations call and thats why i had a doubt.

My current structure (page/components based translations) was created while i evaluated another library. An example:

const HomePage = () => {
  const t = useTranslations('Mainblock');
  const t1 = useTranslations('MainNavigation');
  const {locale, locales, route} = useRouter();
  const otherLocale = locales?.find((cur) => cur !== locale);
  return (
    <div>
       
      <h1> {t('heading')} </h1>
      <p>
        {t('title')}
      </p>
      <p>
        {t('welcomeMessage')}
      </p>
      <Link href={route} locale={otherLocale}>
        <a>{t1('switchLocale', {locale: otherLocale})}</a>
      </Link>

    </div>
  )
}

export function getStaticProps({locale}: GetStaticPropsContext) {
  return {
    props: {
      messages: {
        ...require(`../messages/shared/${locale}.json`),
        ...require(`../messages/home/${locale}.json`)
      },
      now: new Date().getTime()
    }
  };
}

The t1 method calls a different namespace that i have defined in the 'shared.json' file:

{
...
"MainNavigation": {
        "index": "Home",
        "about": "About",
        "switchLocale": "Switch to {locale, select, fr {French} en {English}}"
    },
...
}

while the 'Mainblock' namespace comes from 'home.json'

{
...
    "Mainblock" : {
         "welcomeMessage": "Welcome to my site",
        "heading": "This is the heading",
        "title": "This is the title"
}
...
}

Jest mocking?

Anyone have any good examples of how to mock next-intl for testing with Jest and react-testing-library?

No matching version found

"npm i next-intl" cause "npm ERR! notarget No matching version found for use-intl@^1.3.11" since 4 hours ago.

OSX 11.4
npm 7.15.1
node version 16.3.0

I removed node_modules , npm cache clean and package-lock and even "npm update" but nothing happened.
finally i used yarn and the error happened again but it show me a list of use-intl versions but there were no 1.3.11 version. so i chose the 1.3.3 version of that and it worked.

log:
ali@Alis-MBP nnr % npm i
npm ERR! code ETARGET
npm ERR! notarget No matching version found for use-intl@^1.3.11.
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.

npm ERR! A complete log of this run can be found in:
npm ERR! /Users/ali/.npm/_logs/2021-06-16T10_37_33_062Z-debug.log

Errors/Warnings during build

Hey there! First off I'd like to say thanks for the library and, at the same time, apologize if this isn't the right place for questions.

I've been using this library to translate a website and during build time on Netlify I keep seeing these errors:

NOTIFY Error: [missing key] languages.es
    at handleMessageFallback

This happens for every key, but they're not missing as the site renders properly in all available languages. All static pages are translated (I checked the HTML files Next generated.)

Our _app.js uses the provider like this:

import { NextIntlProvider, IntlErrorCode } from 'next-intl';
import Bugsnag, { ErrorBoundary } from '@/bugsnag'
import ErrorPage from '@/pages/_error';

const MyApp = ({ Component, pageProps }) => {
  const handleIntlError = error => {
    if (error.code !== IntlErrorCode.MISSING_MESSAGE) {
      Bugsnag.notify(error);
    }
  };

  const handleMessageFallback = ({ namespace, key, error }) => {
    if (process && process.env.NODE_ENV !== 'production') {
      return `[missing key] ${namespace}.${key}`;
    }

    if (error.code === IntlErrorCode.MISSING_MESSAGE) {
      Bugsnag.notify(new Error(`[missing key] ${namespace}.${key}`));
      return key;
    }
  };

  return (
    <ErrorBoundary FallbackComponent={ErrorPage}>
      <NextIntlProvider messages={pageProps.messages} onError={handleIntlError} getMessageFallback={handleMessageFallback}>
        <Component {...pageProps} />
      </NextIntlProvider>
    </ErrorBoundary>
  );
};

export default MyApp;

If I console.log(pageProps.messages) all the keys are logged as expected. Client and server side.

On pages I'm accessing messages through getStaticProps and getServerSideProps by returning a messages prop:

export async function getServerSideProps ({ locale }) {
  return {
    props: {
      messages: require(`@/locales/${locale}.json`)
    }
  };
}

Let me know if you need more info. I tried to simplify the snippets by removing unrelated code.

Thanks!

Allow a custom format for variables

Is your feature request related to a problem? Please describe.
All of our translations use the following format to interpolate variables; {{ variable }}, next-intl uses { variable }.
This creates 2 problems for us,

  1. Our legacy stack expects {{ variable }} and this is not an easy thing to change, sadly
  2. It would require us to remove a set of brackets from thousands of translations

Describe the solution you'd like
A way to customize what the format for interpolation looks like. Maybe something on the provider like interpolationOptions={{ openingFormat: "{{", closingFormat: "}}" }}

Describe alternatives you've considered
We tried doing a simple find & replace over our translations to change it to { } but that isn't flawless.

Layouts and next-intl

i have a (normal coplexity) layout structure in my nextjs project:
i have a Layout.js basic component:

     import Footer from './Footer';
     import Newsletter from './Newsletter';
     import SocialHeader from './SocialHeader';
     export default function Layout({ children }) {
       return (
         <>
             <SocialHeader />
             <Header />
             <main>{children}</main>
             <Newsletter />
             <Footer />
         </>
       );
     }

Then i have a HomeLayout.js


export default function Layout({ children }) {
  return (
    <>
      <Hero />
      <main>{children}</main>
    </>
  );
}

in my home page i use the getLayout this way (and in other pages the basic layout):

  return (
    <Layout>
      <HomeLayout>{page}</HomeLayout>
    </Layout>
  );
};

the _app.js is wrapped in the next-intl provider, but it wraps only the main component, and not the layout

  import '../styles/globals.css';
  import Script from 'next/script';
  import { NextIntlProvider } from 'next-intl';
  function MyApp({ Component, pageProps }) {
    const getLayout = Component.getLayout || ((page) => page);

    return getLayout(
      <>
        <NextIntlProvider messages={pageProps.messages}>
          <Head>
            <meta content="width=device-width, initial-scale=1" name="viewport" />
          </Head>
          <Script>
          <Component {...pageProps} />
        </NextIntlProvider>
      </>
    );
  }
  export default MyApp;

everytime i try to use translation in a layout component (footer for example) i got an error, and it says i did not add the provider

any idea on how to solve it? i guess i have to use the provider in layout, but i cant access messages there

Support arrays for dynamic rendering and component reuse

Is your feature request related to a problem? Please describe.
Given a component Section that is rendering 2 paragraphs:

const Section = () => (
  <>
    <h2>{t("title")}<h2>
    {t("p1") !== "" && <p>{t("p1")}</p>}
    {t("p2") !== "" && <p>{t("p2")}</p>}
  </>
)

that could be used on multiple pages and layouts, one must check for endless paragraphs if they exist in the locale and render them. So if "contact" page has 2 paragraphs, this is fine. But what if "imprint" had 3 or more?

Describe the solution you'd like

"title": "imprint",
"paragraphs": [
  "p1...",
  "p2...",
  "p3..."
]

and in the component:

const Section = () => (
  <>
    <h2>{t("title")}<h2>
    {t("paragraphs").map(text => (
      <p>{text}</p>
    ))}
  </>
)

Describe alternatives you've considered
The only alternative I see now is the one in the problem description.

Additional context
The code snippets above show all relevant parts.

Add support for useTranslation in an API route (pages/api/*)

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

I am looking for an i18n-library that I can use in my Next app on both the client- and server-side (especially in API routes). At the moment I am using https://github.com/isaachinman/next-i18next, which does not solve the problem. I am also about to test https://github.com/vinissimus/next-translate#gett, which could be useful as well.

But I asked myself if next-intl could solve that problem as well for me.

In my current use case I try to find a way to use https://react-pdf.org/ in my current Next setup.

Describe the solution you'd like

Add pages/api/* support, like:

import useApiTranslations from 'next-intl/useApiTranslations'

export default async function handler(req, res) {
  const t = await useApiTranslations(req.query.__nextLocale, 'common')
  const title = t('title')

  res.statusCode = 200
  res.setHeader('Content-Type', 'application/json')
  res.end(JSON.stringify({ title }))
}

ATM it is not possible to use it for instance because of this line:

import {useRouter} from 'next/router';

Describe alternatives you've considered

As mentioned above, the idea came to me after seeing the getT feature in next-translate.

Export return type of useTranslations

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

Export the return type of useTranslations as a interface or type so i can use it as a function parameter type

Describe the solution you'd like

Export the return type

interface useTranslationsProps {
    (key: string, values?: Record<string, string | number | boolean | Date | null | undefined> | undefined, formats?: Partial<Formats> | undefined): string;
    rich: (key: string, values?: Record<string, string | number | boolean | Date | ((children: ReactNode) => ReactNode) | null | undefined> | undefined, formats?: Partial<Formats> | undefined) => string | ReactElement | ReactNodeArray;
    raw(key: string): any;
}

I keep getting missing messages errors

Using the latest next 10.x

I have my file setup as:

src
-- messages
-- -- header
-- -- -- en.json

_app has:

MyApp.getInitialProps = async function getInitialProps(context) {
  const { locale } = context.router
  return {
    ...(await NextApp.getInitialProps(context)),
    messages: require(`../messages/header/${locale}.json`),
  }
}

I have checked that it gets locale correctly but console keeps throwing errors:

 code: 'MISSING_MESSAGE',
  originalMessage: 'No messages available at `undefined`.'

Any ideas what I could be missing here?

Enable usage in backend code

Is your feature request related to a problem? Please describe.
I would like to use next-intl in backend code, specifically I'd like to send an email based on the users language. There is no react rendering and hence no context with the translations available. If I understand correctly, then #40 still involved react rendering (although to a pdf).

Describe the solution you'd like
Ideally I'd like to setup some intl context statically in the backend and then in an api route load messages based on the current users language and have a translation function available.

Describe alternatives you've considered
Probably using https://formatjs.io/docs/intl could work, but I'm afraid there's quite a bit to rebuild, since e.g. the message lookup functionality is implemented in the useTranslations hook.

Additional context
Thanks for working on this library :-)

Reload on message file updates

Hi @amannn!
First of all: Great work! I really like the simplicity and flexibility of this lib πŸ‘

I started experimenting with it in a new project today (using [email protected]) and one thing is bothering me: I need to manually stop and restart the Next.js dev server to make updates on json message files visible. Do you have the same issue in your dev-setup or did you find a way to restart the server automatically?

Default Rich Text Elements

Is your feature request related to a problem? Please describe.
If you are using multiple rich text messages which contain the same elements/tags with styling, it is hard to maintain consistency between all of them.

Describe the solution you'd like
I would like to configure some default elements/tags in the IntlProvider similar to (or exactly like) react-intl handles this problem using default rich text elements. This solution would provide consistency and reduce redundancy in each component.

useTranslations in class components

Is your feature request related to a problem? Please describe.
I want to use useTranslations in class components but seems like I can't do this out of the box.

Describe the solution you'd like
May be add a hoc withNextIntl or something like that.

When plan to release new version to match next@11 ?

while upgrade next from 10 to v11, it give us npm module dependencies issue.

npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/next
npm ERR!   next@"^11.0.0" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer next@"^10.0.0" from [email protected]
npm ERR! node_modules/next-intl
npm ERR!   next-intl@"^1.3.3" from the root project
npm ERR! 

The current leatest version for next-intl is 1.3.3 , when plan to release new version to match next@11?

Translate a component used in different pages

Is your feature request related to a problem? Please describe.
I can't seem to find any information related to this question in the docs or the issues in here. I have a navbar which I would like to translate, but if the page itself doesn't have the getStaticProps, I get the "no message provider" error.

Describe the solution you'd like
I would like further explanation of how to use this library without the getStaticProps, because this is only valid for pages, but not for components. Another possible solution is allowing for an alternative message when the component is rendered without it being able to find the provider messages.

Describe alternatives you've considered
I've tried fetching the data in the client side to fill the "messages" prop, but I didn't seem to succeed. I would appreciate to be enlightened if I'm doing something wrong too.

Accept timezone

react-intl supports a few more options on its provider. Should we support some of them as well? E.g. formats could be interesting.

Support for message formats other than ICU

looking for libraries to use for i18n I was surprised to see how many echo systems there are for the locale messages themselves.
It seemed like they live in different worlds since all libraries don't even address supporting the formats, so the market is very fragmented and not efficient.

So I think it would be smart to support other formats, a low-hanging fruit to achieve more users/dev.

For example, the i18next default format is different than the 'ICU' standard used here in next-intl.
I don't know how really different it is (I'm not using all features, like plural and date formating etc...), but I think that the diff is easy to work with.

In my case trying next-intl on locales from an i18next project, I had to do just two things:

  1. variables: replace in locale files all {{ name }} with ICU's {name} (one { instead of two)
    I wrote this regex for it: .replace(/\{\{ *(\w+) *\}\}/g, '{$1}')
  2. name space delimiter: replace all keys used in code from NAMESPACE: etc.. with NAMESPACE. etc (. instead of :)

So actually supporting i18next default format seems to be very easy.
(and my motivation to not use i18next on a nextjs project was a heavy performance hit on client side, including having all languages locales sent to browser)

  • I guess I'm not alone in that, there should be a simple way to be versatile with the formats

How to mock useTranslation and test it with jest

Describe the bug
A clear and concise description of what the bug is.

To Reproduce

Please provide a CodeSandbox that illustrates the problem (template).

Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Documentation for using next-intl with SSR instead of static generation

Is your feature request related to a problem? Please describe.
I need to internationalize my site that has both static content that can be translated and server generated content to display on that page. Hence, I need to use both getStaticsProps and getServerSideProps. However, Next.js does not allow me to use both functions so either I have to opt into no translations or opt into no dynamic content on load. I can't afford to lose either feature so I need a path that I can use next-intl in both ways.

Describe the solution you'd like
If there's a way to load translations at the app level instead of statically per page, I'd take that solution. Using getStaticProps isn't going to continue to work for my use case.

Describe alternatives you've considered
I can't find it anymore but someone at one point suggested doing something in _document or _app where you preload. I'd be okay with this solution but I can't find a way to do it again.

Additional context
I am trying to get Vercel to make both prop rendering methods available vercel/next.js#11424

useTranslations populates a new 't' on every render

If there is a component/useEffect/useCallback that has t as a prop/dependency, it makes it rerender/rerun since t is changing.

I assume it should change only on locale change (at least the case I was using)

I'm using this as a workaround:

   const t = useCallback(useTranslations(), [locale])

404 page

Having the dependency on messages being injected on the page, becomes a problem when the page is the 404 page.

My _app.tsx has a layout that includes:
HEADER
WHATEVER_PAGE
FOOTER

the 404 page will load between the header and the footer. Both require the messages.

I've tried getServierSideProps, getStaticProps and though it works on develop, after build I have warnings and the header and footer do NOT have the translations.

Load multiple namespaces

Is your feature request related to a problem? Please describe.
We have lots of duplicated translation strings

Describe the solution you'd like
To be able to pass an array of namespaces so that we can put common translations in common json files.

Describe alternatives you've considered
Putting everything in one namespace and adding namespacing on the translation key

Storybook Integration

Storybook is very useful for testing components in isolation, most of said components use the useTranslation hook and Storybook doesn't recognize it

A Storyook addon similar to the one used by react-intl would be useful https://storybook.js.org/addons/storybook-addon-intl/

One alternative is passing the hook from the parent to the child that way the child is unaware of the hook and props can be used.

Extract `use-intl`

The integration with Next.js is really minimal. I think we could extract the common API to be used in non-Next.js apps and make next-intl a small wrapper on top. Note that for shared utilities we should use a common identifier then. E.g. we can't have NextIntlErrorCode but should use something like IntlErrorCode (related to #8).

An existing API that needs to be renamed is NextIntlProvider.

'IntlErrorCode' is not exported from 'next-intl'

Using v0.4.0, I've run into the above error attempting to follow the error handling example from here in the README.

image

My code looks like this:

// ...
import { NextIntlProvider, IntlErrorCode } from "next-intl"
// ...

function onIntlError(error) {
  if (error.code === IntlErrorCode.MISSING_MESSAGE) {
    console.warn(`⚠️ Translation missing for ...`)
    console.log(error)
  } else {
    // TODO log to Sentry
  }
}

export default function App({ Component, pageProps, translations }) {
  return (
    <NextIntlProvider messages={translations} onError={onIntlError}>
      <Component {...pageProps} />
    </NextIntlProvider>
  )
}

App.getInitialProps = async context => {
  const { router } = context
  const { locale, defaultLocale } = router

  const translations = await getTranslations({
    locale,
    defaultLocale
  })

  const appProps = await NextApp.getInitialProps(context)

  return {
    ...appProps,
    locale,
    translations
  }
}

For the moment, I've just been trying to log out the full details of the error so I can see what's on it, but I'm running into this error. Any ideas what I'm missing? Did something change in a recent release since this section of the README was written?

Optional translations

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

It would be good if some translations could be marked as optional, so no error is reported.

Describe the solution you'd like

Either an API to ask if a translation is available to conditionally render it, or an API to suppress the error in this case.

Probably t.has(…) would be the best option here as it can be used to check for translations before using either t, t.rich, t.raw etc.

Describe alternatives you've considered

Adding empty strings in the messages if the label is not relevant for a particular scenario (i.e. "message": "").

If you're using the VSCode integration for next-intl via i18n Ally, you can add empty messages for new keys via "i18n-ally.keepFulfilled": true.

I'm currently unsure if next-intl needs built-in support for this, or if it can be solved with tooling. I guess the question is: "Is this translation missing currently or is it not intended at all?".

This could also be solved via a combination of useMessages and lodash/get, e.g. in a custom hook.

t.raw is not a function

Describe the bug
Hi,
first off I'm really sorry if I waste your time on this, it is probably just my confusion.
I use [email protected] and try to use t.raw to access an array of strings from my translation to render a list of product features but t.raw seems to be undefined.

To Reproduce
I reproduced this using use-intl instead of next-intl as mocking next/router in codesandbox sucks.
https://codesandbox.io/s/hidden-pine-rsmnl?file=/src/App.js

Steps to reproduce the behavior:

  1. See error

Expected behavior
I'd expect t.raw to be there and return the raw array so I can render my list from the input strings.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.