Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: Add docs for Next.js 13 and the app directory #150

Merged
merged 8 commits into from
Dec 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@

![Gzipped size](https://badgen.net/bundlephobia/minzip/next-intl) ![Tree shaking supported](https://badgen.net/bundlephobia/tree-shaking/next-intl) [<img src="https://img.shields.io/npm/dw/next-intl.svg" />](https://www.npmjs.com/package/next-intl)

<hr />

**🚀 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.

<hr />

## 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.
Expand Down
3 changes: 2 additions & 1 deletion packages/website/pages/docs/meta.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"getting-started": "Getting started",
"usage": "Usage guide",
"faq": "FAQ"
"faq": "FAQ",
"next-13": "Next.js 13 (preview)"
}
178 changes: 178 additions & 0 deletions packages/website/pages/docs/next-13.mdx
Original file line number Diff line number Diff line change
@@ -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.

<Callout>
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.
</Callout>

**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 (
<NextIntlServerProvider locale={locale} messages={messages}>
{children}
</NextIntlServerProvider>
);
}
```

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 <h1>{t('title')}</h1>;
}
```

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 <InteractiveClientComponent title={t('title')} />;
}
```

```tsx
// app/[locale]/InteractiveClientComponent.tsx
'use client';

import {useEffect} from 'react';

function InteractiveClientComponent({title}) {
useEffect(() => alert(title), []);
return <h1>{title}</h1>;
}
```

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 (
<NextIntlClientProvider locale={locale} messages={messages}>
{children}
</NextIntlClientProvider>
);
}
```

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 <h1>{t('title')}</h1>;
}
```

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.
16 changes: 16 additions & 0 deletions packages/website/pages/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ title: Internationalization for Next.js
---

import Bleed from 'nextra-theme-docs/bleed';
import Callout from 'nextra-theme-docs/callout';

<div style={{padding: '60px 0'}}>
<h1 className="text-center md:text-5xl">next-intl</h1>
Expand All @@ -16,6 +17,21 @@ import Bleed from 'nextra-theme-docs/bleed';
</div>
</div>

<div
style={{
padding: 20,
background: '#F0FDF4',
border: '1px solid #4ade80',
borderRadius: 4
}}
>
<b style={{color: '#15803d'}}>✨ New ✨: </b> `next-intl` is adding support
for
<b>Next.js 13</b> 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.
</div>

## 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.
Expand Down