diff --git a/README.md b/README.md index f446e2200..1f559c371 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. 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..eea726726 --- /dev/null +++ b/packages/website/pages/docs/next-13.mdx @@ -0,0 +1,178 @@ +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.5 +``` + +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 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, this language will take precedence from now on. +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) ([demo](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(title), []); + 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. + +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`: + +```tsx +import {NextIntlClientProvider} from 'next-intl/client'; +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 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 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. + +## 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.