From 74a474d2eddfd21398d9a006eb7737d977d82633 Mon Sep 17 00:00:00 2001 From: Jan Amann Date: Thu, 8 Dec 2022 16:21:46 +0100 Subject: [PATCH 1/8] docs: Add docs for Next.js 13 and the `app` directory --- packages/website/pages/docs/meta.json | 3 +- packages/website/pages/docs/next-13.mdx | 176 ++++++++++++++++++++++++ packages/website/pages/index.mdx | 16 +++ 3 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 packages/website/pages/docs/next-13.mdx diff --git a/packages/website/pages/docs/meta.json b/packages/website/pages/docs/meta.json index 31185f39e..98589147c 100644 --- a/packages/website/pages/docs/meta.json +++ b/packages/website/pages/docs/meta.json @@ -1,5 +1,6 @@ { "getting-started": "Getting started", "usage": "Usage guide", - "faq": "FAQ" + "faq": "FAQ", + "next-13": "Next.js 13 (preview)" } \ No newline at end of file diff --git a/packages/website/pages/docs/next-13.mdx b/packages/website/pages/docs/next-13.mdx new file mode 100644 index 000000000..a1172ab20 --- /dev/null +++ b/packages/website/pages/docs/next-13.mdx @@ -0,0 +1,176 @@ +import Callout from 'nextra-theme-docs/callout'; + +# Next.js 13 (preview) + +Next.js 13 introduces the `app` directory, which includes support for [React Server Components](https://beta.nextjs.org/docs/rendering/server-and-client-components). `next-intl` is adopting the new capabilities and is currently offering a preview to early adopters, who are already building apps with the `app` directory. + + + The `app` directory is currently in beta, patterns are still emerging and APIs + may change. Please **use this at your own risk**, knowing that you might have + to face a migration effort when the `app` directory becomes stable. + `next-intl` tries to stay up to date with the latest developments on the + Next.js side, but during this period there can be unexpected issues. + + +**Current pre-release:** + +``` +npm install next-intl@2.10.0-alpha.4 +``` + +This pre-release was tested with `next@13.0.6`. + +## Getting started + +[Create a Next.js 13 app that uses the `app` directory](https://beta.nextjs.org/docs/installation) if you haven't done so already. The goal is to prefix all routes with the `locale`, so we can retrieve it as a [dynamic segment](https://beta.nextjs.org/docs/routing/defining-routes#dynamic-segments) and use it to configure `next-intl`. + +1. Create the following file structure: + +``` +├── messages (1) +│ ├── en.json +│ └── ... +├── app +│ ├── [locale] +│ │ ├── layout.tsx (2) +│ │ └── page.tsx (3) +│ └── ... +└── middleware.tsx (4) +``` + +2. Set up messages for a language, e.g. in `messages/en.json` (1): + +```json +{ + "Index": { + "title": "Hello world!" + } +} +``` + +3. Configure `NextIntlServerProvider` in `app/[locale]/layout.tsx` (2): + +```tsx +import {NextIntlServerProvider} from 'next-intl/server'; +import {notFound} from 'next/navigation'; + +export default async function LocaleLayout({children, params: {locale}}) { + let messages; + try { + messages = (await import(`../../messages/${locale}.json`)).default; + } catch (error) { + notFound(); + } + + return ( + + {children} + + ); +} +``` + +4. Use your messages on in `app/[locale]/page.tsx` (3): + +```tsx +import {useTranslations} from 'next-intl'; + +export default function Index() { + const t = useTranslations('Index'); + return

{t('title')}

; +} +``` + +5. Create a [middleware](https://nextjs.org/docs/advanced-features/middleware) that handles redirects: + +```tsx +import {createIntlMiddleware} from 'next-intl/server'; + +// This middleware intercepts requests to `/` and will redirect +// to one of the configured locales instead (e.g. `/en`). +// A cookie is set in the background, so if the user switches +// to a new language, the decision will be remembered. +export default createIntlMiddleware({ + locales: ['en', 'de'], + defaultLocale: 'en' +}); +``` + +That's all you need to do to start using translations in Server Components! + +If you've encountered an issue, you can [explore the code for a working example](https://github.com/amannn/next-intl/tree/feat/next-13-rsc/packages/example-next-13) ([deployed version](https://csb-k2ien9-7ytkomg4x-amann.vercel.app/en)). + +## Using translations in Client Components + +If you need to use translations in Client Components, the best approach is to pass the generated labels as props. + +```tsx +// app/[locale]/page.tsx +import {useTranslations} from 'next-intl'; +import InteractiveClientComponent from './InteractiveClientComponent'; + +export default function Index() { + const t = useTranslations('Index'); + return ; +} +``` + +```tsx +// app/[locale]/InteractiveClientComponent.tsx +'use client'; + +import {useEffect} from 'react'; + +function InteractiveClientComponent({title}) { + useEffect(() => alert('Hello!'), []); + return

{title}

; +} +``` + +This way your messages never leave the server and the client only needs to load the code that is necessary for initializing your interactive components. + +## Migrating from the `pages` folder + +If you have existing code from the `pages` folder that you want to migrate, you can use `NextIntlProvider` (instead of `NextIntlServerProvider`) in `app/[locale]/layout.tsx`: + +```tsx +import {NextIntlProvider} from 'next-intl'; +import {notFound} from 'next/navigation'; + +export default async function LocaleLayout({children, params: {locale}}) { + let messages; + try { + messages = (await import(`../../../messages/${locale}.json`)).default; + } catch (error) { + notFound(); + } + + return ( + + {children} + + ); +} +``` + +By doing this, the messages automatically become available for all Client Components that are rendered in your app. Note that you have to make use of `'use client';` in all components that use features from `next-intl` if you use this approach. + +```tsx +// app/[locale]/page.tsx +'use client'; + +import {useTranslations} from 'next-intl'; + +export default function Index() { + const t = useTranslations('Index'); + return

{t('title')}

; +} +``` + +If you're transitioning your components, you can also use both providers to have messages available in both Server as well as Client Components. + +Also note that [internationalized routing](https://nextjs.org/docs/advanced-features/i18n-routing) is no longer supported natively by Next.js, therefore you should use the middleware mentioned above. + +## Providing feedback + +If you have feedback about using `next-intl` in the `app` dir, I'd be happy to hear from you! Feel free to leave feedback in [the PR which implements](https://github.com/amannn/next-intl/pull/149) the new features. diff --git a/packages/website/pages/index.mdx b/packages/website/pages/index.mdx index eac82c91a..dbf9358ac 100644 --- a/packages/website/pages/index.mdx +++ b/packages/website/pages/index.mdx @@ -3,6 +3,7 @@ title: Internationalization for Next.js --- import Bleed from 'nextra-theme-docs/bleed'; +import Callout from 'nextra-theme-docs/callout';

next-intl

@@ -16,6 +17,21 @@ import Bleed from 'nextra-theme-docs/bleed';
+
+ ✨ New ✨: `next-intl` is adding support + for + Next.js 13 and the [`app` directory](https://beta.nextjs.org/docs/routing/fundamentals). + A preview version with support for React Server Components is [now available](/docs/next-13) + for early adopters. +
+ ## Features This library complements the [internationalized routing](https://nextjs.org/docs/advanced-features/i18n-routing) capabilities of Next.js by managing translations and providing them to components. From 6e4727fd60f8347e9f31ed4d7bb9f122fb7b1415 Mon Sep 17 00:00:00 2001 From: Jan Amann Date: Thu, 8 Dec 2022 16:25:34 +0100 Subject: [PATCH 2/8] Banner in readme --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index f446e2200..e393ae112 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,12 @@ ![Gzipped size](https://badgen.net/bundlephobia/minzip/next-intl) ![Tree shaking supported](https://badgen.net/bundlephobia/tree-shaking/next-intl) [](https://www.npmjs.com/package/next-intl) +
+ +**✨ New ✨**: `next-intl` is adding support for **Next.js 13** and the [`app` directory](https://beta.nextjs.org/docs/routing/fundamentals). A preview version with support for React Server Components is [now available](https://next-intl-git-docs-next-13-amann.vercel.app/docs/next-13) for early adopters. + +
+ ## Features This library complements the [internationalized routing](https://nextjs.org/docs/advanced-features/i18n-routing) capabilities of Next.js by managing translations and providing them to components. From d122ed4b2202d61946016c7e44d73b31c8a75e4a Mon Sep 17 00:00:00 2001 From: Jan Amann Date: Thu, 8 Dec 2022 16:32:22 +0100 Subject: [PATCH 3/8] Wording --- packages/website/pages/docs/next-13.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/website/pages/docs/next-13.mdx b/packages/website/pages/docs/next-13.mdx index a1172ab20..6191bcec6 100644 --- a/packages/website/pages/docs/next-13.mdx +++ b/packages/website/pages/docs/next-13.mdx @@ -167,7 +167,7 @@ export default function Index() { } ``` -If you're transitioning your components, you can also use both providers to have messages available in both Server as well as Client Components. +If you're transitioning your components, you can use both providers to have messages available in both Server as well as Client Components. Also note that [internationalized routing](https://nextjs.org/docs/advanced-features/i18n-routing) is no longer supported natively by Next.js, therefore you should use the middleware mentioned above. From ecdef5faeb8289ebe5160c43c38c140b190fb80e Mon Sep 17 00:00:00 2001 From: Jan Amann Date: Thu, 8 Dec 2022 17:36:07 +0100 Subject: [PATCH 4/8] Update instructions --- packages/website/pages/docs/next-13.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/website/pages/docs/next-13.mdx b/packages/website/pages/docs/next-13.mdx index 6191bcec6..8b66f4d54 100644 --- a/packages/website/pages/docs/next-13.mdx +++ b/packages/website/pages/docs/next-13.mdx @@ -15,7 +15,7 @@ Next.js 13 introduces the `app` directory, which includes support for [React Ser **Current pre-release:** ``` -npm install next-intl@2.10.0-alpha.4 +npm install next-intl@3.0.0-alpha.1 ``` This pre-release was tested with `next@13.0.6`. @@ -131,10 +131,10 @@ This way your messages never leave the server and the client only needs to load ## Migrating from the `pages` folder -If you have existing code from the `pages` folder that you want to migrate, you can use `NextIntlProvider` (instead of `NextIntlServerProvider`) in `app/[locale]/layout.tsx`: +If you have existing code from the `pages` folder that you want to migrate, you can use `NextIntlClientProvider` (instead of `NextIntlServerProvider`) in `app/[locale]/layout.tsx`: ```tsx -import {NextIntlProvider} from 'next-intl'; +import {NextIntlClientProvider} from 'next-intl/client'; import {notFound} from 'next/navigation'; export default async function LocaleLayout({children, params: {locale}}) { @@ -146,9 +146,9 @@ export default async function LocaleLayout({children, params: {locale}}) { } return ( - + {children} - + ); } ``` From acd85d540e66f98a2ac6e7a259d383bea1d6fbc2 Mon Sep 17 00:00:00 2001 From: Jan Amann Date: Thu, 8 Dec 2022 17:46:27 +0100 Subject: [PATCH 5/8] Update version --- packages/website/pages/docs/next-13.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/website/pages/docs/next-13.mdx b/packages/website/pages/docs/next-13.mdx index 8b66f4d54..e4cc1e577 100644 --- a/packages/website/pages/docs/next-13.mdx +++ b/packages/website/pages/docs/next-13.mdx @@ -15,7 +15,7 @@ Next.js 13 introduces the `app` directory, which includes support for [React Ser **Current pre-release:** ``` -npm install next-intl@3.0.0-alpha.1 +npm install next-intl@2.10.0-alpha.5 ``` This pre-release was tested with `next@13.0.6`. From d6b6869e56012b4f7547669b9a08b1f3f5741421 Mon Sep 17 00:00:00 2001 From: Jan Amann Date: Thu, 8 Dec 2022 17:56:18 +0100 Subject: [PATCH 6/8] Note about client provider --- packages/website/pages/docs/next-13.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/website/pages/docs/next-13.mdx b/packages/website/pages/docs/next-13.mdx index e4cc1e577..542a08124 100644 --- a/packages/website/pages/docs/next-13.mdx +++ b/packages/website/pages/docs/next-13.mdx @@ -129,6 +129,8 @@ function InteractiveClientComponent({title}) { This way your messages never leave the server and the client only needs to load the code that is necessary for initializing your interactive components. +If you absolutely need to use functionality from `next-intl` on the client side, you can wrap the respective components with `NextIntlClientProvider` ([example code](https://github.com/amannn/next-intl/blob/feat/next-13-rsc/packages/example-next-13-advanced/src/components/client/02-MessagesOnClientCounter/Counter.tsx)). Note however that this will increase your client bundle size. + ## Migrating from the `pages` folder If you have existing code from the `pages` folder that you want to migrate, you can use `NextIntlClientProvider` (instead of `NextIntlServerProvider`) in `app/[locale]/layout.tsx`: From 91c8e26bb5615daa080a89c04aa8afc2c41945e3 Mon Sep 17 00:00:00 2001 From: Jan Amann Date: Thu, 8 Dec 2022 18:33:03 +0100 Subject: [PATCH 7/8] Wording --- README.md | 2 +- packages/website/pages/docs/next-13.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e393ae112..1f559c371 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@
-**✨ New ✨**: `next-intl` is adding support for **Next.js 13** and the [`app` directory](https://beta.nextjs.org/docs/routing/fundamentals). A preview version with support for React Server Components is [now available](https://next-intl-git-docs-next-13-amann.vercel.app/docs/next-13) for early adopters. +**🚀 New ✨**: `next-intl` is adding support for **Next.js 13** and the [`app` directory](https://beta.nextjs.org/docs/routing/fundamentals). A preview version with support for React Server Components is [now available](https://next-intl-git-docs-next-13-amann.vercel.app/docs/next-13) for early adopters.
diff --git a/packages/website/pages/docs/next-13.mdx b/packages/website/pages/docs/next-13.mdx index 542a08124..766d90bbb 100644 --- a/packages/website/pages/docs/next-13.mdx +++ b/packages/website/pages/docs/next-13.mdx @@ -98,7 +98,7 @@ export default createIntlMiddleware({ That's all you need to do to start using translations in Server Components! -If you've encountered an issue, you can [explore the code for a working example](https://github.com/amannn/next-intl/tree/feat/next-13-rsc/packages/example-next-13) ([deployed version](https://csb-k2ien9-7ytkomg4x-amann.vercel.app/en)). +If you've encountered an issue, you can [explore the code for a working example](https://github.com/amannn/next-intl/tree/feat/next-13-rsc/packages/example-next-13) ([demo](https://csb-k2ien9-7ytkomg4x-amann.vercel.app/en)). ## Using translations in Client Components From 6eb82f15e65af37188d1eecefa45a825daece03d Mon Sep 17 00:00:00 2001 From: Jan Amann Date: Thu, 8 Dec 2022 18:50:06 +0100 Subject: [PATCH 8/8] Wording --- packages/website/pages/docs/next-13.mdx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/website/pages/docs/next-13.mdx b/packages/website/pages/docs/next-13.mdx index 766d90bbb..eea726726 100644 --- a/packages/website/pages/docs/next-13.mdx +++ b/packages/website/pages/docs/next-13.mdx @@ -70,7 +70,7 @@ export default async function LocaleLayout({children, params: {locale}}) { } ``` -4. Use your messages on in `app/[locale]/page.tsx` (3): +4. Use your messages in `app/[locale]/page.tsx` (3): ```tsx import {useTranslations} from 'next-intl'; @@ -87,9 +87,9 @@ export default function Index() { import {createIntlMiddleware} from 'next-intl/server'; // This middleware intercepts requests to `/` and will redirect -// to one of the configured locales instead (e.g. `/en`). -// A cookie is set in the background, so if the user switches -// to a new language, the decision will be remembered. +// to one of the configured locales instead (e.g. `/en`). A cookie +// is set in the background, so if the user switches to a new +// language, this language will take precedence from now on. export default createIntlMiddleware({ locales: ['en', 'de'], defaultLocale: 'en' @@ -122,7 +122,7 @@ export default function Index() { import {useEffect} from 'react'; function InteractiveClientComponent({title}) { - useEffect(() => alert('Hello!'), []); + useEffect(() => alert(title), []); return

{title}

; } ``` @@ -155,7 +155,7 @@ export default async function LocaleLayout({children, params: {locale}}) { } ``` -By doing this, the messages automatically become available for all Client Components that are rendered in your app. Note that you have to make use of `'use client';` in all components that use features from `next-intl` if you use this approach. +By doing this, the messages become available for all Client Components that are rendered in your app. Note that you have to make use of `'use client';` in all components that use features from `next-intl` if you use this approach. ```tsx // app/[locale]/page.tsx @@ -169,7 +169,7 @@ export default function Index() { } ``` -If you're transitioning your components, you can use both providers to have messages available in both Server as well as Client Components. +If you're transitioning your components to the `app` directory, you can use both providers to have messages available in Server as well as Client Components. Also note that [internationalized routing](https://nextjs.org/docs/advanced-features/i18n-routing) is no longer supported natively by Next.js, therefore you should use the middleware mentioned above.