You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat!: Don't read a default for useLocale from useParams.locale on the client side, but rely on NextIntlClientProvider being used (preparation for dynamicIO) (#1541)
Previously, `useParams.locale` was consulted when reading from
`useLocale()` on the client side, allowing to use this API even when no
`NextIntlClientProvider` is used.
This behavior has now been removed because:
1. Reading from `useParams().locale` doesn't apply if you're using an
[App Router
setup](https://next-intl-docs.vercel.app/docs/getting-started/app-router)
without i18n routing.
2. Reading from `useParams()` might require additional work from the
developer in the future to work with the upcoming
[`dynamicIO`](https://nextjs.org/docs/canary/app/api-reference/config/next-config-js/dynamicIO)
rendering mode like adding `'use cache'` or a `<Suspense />` boundary.
Therefore, if you use any features from `next-intl` on the client side,
you should now add a `NextIntlClientProvider` in the root layout and
wrap all relevant components:
```tsx
import {NextIntlClientProvider} from 'next-intl';
export default async function LocaleLayout(/* ... */) {
// ...
return (
<html lang={locale}>
<body>
<NextIntlClientProvider>
{children}
</NextIntlClientProvider>
</body>
</html>
);
}
```
Note that also navigation APIs like `Link` rely on `useLocale`
internally.
Copy file name to clipboardExpand all lines: docs/src/pages/docs/environments/server-client-components.mdx
+4-1
Original file line number
Diff line number
Diff line change
@@ -69,14 +69,17 @@ These functions are available:
69
69
70
70
Components that aren't declared with the `async` keyword and don't use interactive features like `useState`, are referred to as [shared components](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md#sharing-code-between-server-and-client). These can render either as a Server or Client Component, depending on where they are imported from.
71
71
72
-
In Next.js, Server Components are the default, and therefore shared components will typically execute as Server Components.
72
+
In Next.js, Server Components are the default, and therefore shared components will typically execute as Server Components:
73
73
74
74
```tsx filename="UserDetails.tsx"
75
75
import {useTranslations} from'next-intl';
76
76
77
77
exportdefaultfunction UserDetails({user}) {
78
78
const t =useTranslations('UserProfile');
79
79
80
+
// This component will execute as a Server Component by default.
81
+
// However, if it is imported from a Client Component, it will
<summary>Which values can the `requestLocale` parameter hold?</summary>
186
+
187
+
While the `requestLocale` parameter typically corresponds to the `[locale]` segment that was matched by the middleware, there are three special cases to consider:
188
+
189
+
1.**Overrides**: When an explicit `locale` is passed to [awaitable functions](/docs/environments/actions-metadata-route-handlers) like `getTranslations({locale: 'en'})`, then this value will be used instead of the segment.
190
+
1.**`undefined`**: The value can be `undefined` when a page outside of the `[locale]` segment renders (e.g. a language selection page at `app/page.tsx`).
191
+
1.**Invalid values**: Since the `[locale]` segment effectively acts like a catch-all for unknown routes (e.g. `/unknown.txt`), invalid values should be replaced with a valid locale. In addition to this, you might want to call `notFound()` in [the root layout](/docs/getting-started/app-router/with-i18n-routing#layout) to abort the render in this case.
<summary>Which values can the `requestLocale` parameter hold?</summary>
205
+
<Detailsid="locale-change">
206
+
<summary>How can I change the locale?</summary>
196
207
197
-
While the `requestLocale` parameter typically corresponds to the `[locale]` segment that was matched by the middleware, there are three special cases to consider:
208
+
Depending on if you're using [i18n routing](/docs/getting-started/app-router), the locale can be changed as follows:
198
209
199
-
1.**Overrides**: When an explicit `locale` is passed to [awaitable functions](/docs/environments/actions-metadata-route-handlers) like `getTranslations({locale: 'en'})`, then this value will be used instead of the segment.
200
-
1.**`undefined`**: The value can be `undefined` when a page outside of the `[locale]` segment renders (e.g. a language selection page at `app/page.tsx`).
201
-
1.**Invalid values**: Since the `[locale]` segment effectively acts like a catch-all for unknown routes (e.g. `/unknown.txt`), invalid values should be replaced with a valid locale. In addition to this, you might want to call `notFound()` in [the root layout](/docs/getting-started/app-router/with-i18n-routing#layout) to abort the render in this case.
210
+
1.**With i18n routing**: The locale is managed by the router and can be changed by using navigation APIs from `next-intl` like [`Link`](/docs/routing/navigation#link) or [`useRouter`](/docs/routing/navigation#userouter).
211
+
2.**Without i18n routing**: You can change the locale by updating the value where the locale is read from (e.g. a cookie, a user setting, etc.). If you're looking for inspiration, you can have a look at the [App Router without i18n routing example](/examples#app-router-without-i18n-routing) that manages the locale via a cookie.
202
212
203
213
</Details>
204
214
@@ -218,41 +228,15 @@ import {getLocale} from 'next-intl/server';
218
228
const locale =awaitgetLocale();
219
229
```
220
230
221
-
### `Locale` type [#locale-type]
222
-
223
-
When passing a `locale` to another function, you can use the `Locale` type for the receiving parameter:
224
-
225
-
```tsx
226
-
import {Locale} from'next-intl';
227
-
228
-
asyncfunction getPosts(locale:Locale) {
229
-
// ...
230
-
}
231
-
```
232
-
233
-
<Callout>
234
-
By default, `Locale` is typed as `string`. However, you can optionally provide
235
-
a strict union based on your supported locales for this type by [augmenting
236
-
the `Locale` type](/docs/workflows/typescript#locale).
237
-
</Callout>
238
-
239
-
<Detailsid="locale-change">
240
-
<summary>How can I change the locale?</summary>
241
-
242
-
Depending on if you're using [i18n routing](/docs/getting-started/app-router), the locale can be changed as follows:
243
-
244
-
1.**With i18n routing**: The locale is managed by the router and can be changed by using navigation APIs from `next-intl` like [`Link`](/docs/routing/navigation#link) or [`useRouter`](/docs/routing/navigation#userouter).
245
-
2.**Without i18n routing**: You can change the locale by updating the value where the locale is read from (e.g. a cookie, a user setting, etc.). If you're looking for inspiration, you can have a look at the [App Router without i18n routing example](/examples#app-router-without-i18n-routing) that manages the locale via a cookie.
246
-
247
-
</Details>
248
-
249
231
<Detailsid="locale-return-value">
250
232
<summary>Which value is returned from `useLocale`?</summary>
251
233
252
-
The returned value is resolved based on these priorities:
234
+
Depending on how a component renders, the returned locale corresponds to:
253
235
254
-
1.**Server Components**: If you're using [i18n routing](/docs/getting-started/app-router), the returned locale is the one that you've either provided via [`setRequestLocale`](/docs/getting-started/app-router/with-i18n-routing#static-rendering) or alternatively the one in the `[locale]` segment that was matched by the middleware. If you're not using i18n routing, the returned locale is the one that you've provided via `getRequestConfig`.
255
-
2.**Client Components**: In this case, the locale is received from `NextIntlClientProvider` or alternatively `useParams().locale`. Note that `NextIntlClientProvider` automatically inherits the locale if the component is rendered by a Server Component.
236
+
1.**Server Components**: The locale represents the value returned in [`i18n/request.ts`](#i18n-request).
237
+
2.**Client Components**: The locale is received from [`NextIntlClientProvider`](#nextintlclientprovider).
238
+
239
+
Note that `NextIntlClientProvider` automatically inherits the locale if it is rendered by a Server Component, therefore you rarely need to pass a locale to `NextIntlClientProvider` yourself.
256
240
257
241
</Details>
258
242
@@ -277,6 +261,24 @@ return (
277
261
278
262
</Details>
279
263
264
+
### `Locale` type [#locale-type]
265
+
266
+
When passing a `locale` to another function, you can use the `Locale` type for the receiving parameter:
267
+
268
+
```tsx
269
+
import {Locale} from'next-intl';
270
+
271
+
asyncfunction getPosts(locale:Locale) {
272
+
// ...
273
+
}
274
+
```
275
+
276
+
<Callout>
277
+
By default, `Locale` is typed as `string`. However, you can optionally provide
278
+
a strict union based on your supported locales for this type by [augmenting
279
+
the `Locale` type](/docs/workflows/typescript#locale).
280
+
</Callout>
281
+
280
282
## Messages
281
283
282
284
The most crucial aspect of internationalization is providing labels based on the user's language. The recommended workflow is to store your messages in your repository along with the code.
0 commit comments