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
After a year of feature development, this release focuses on streamlining the API surface while maintaining the core architecture of `next-intl`. With many improvements already released in [previous minor versions](/blog/next-intl-3-22), this update introduces several enhancements that will improve your development experience and make working with internationalization even more seamless.
13
13
@@ -44,7 +44,7 @@ declare module 'next-intl' {
44
44
}
45
45
```
46
46
47
-
See the updated [TypeScript augmentation](https://v4.next-intl.dev/docs/workflows/typescript) guide.
47
+
See the updated [TypeScript augmentation](/docs/workflows/typescript) guide.
48
48
49
49
## Strictly-typed locale
50
50
@@ -65,7 +65,7 @@ declare module 'next-intl' {
65
65
66
66
By doing so, APIs like `useLocale()` or `<Link />` that either return or receive a `locale` will now pick up your app-specific `Locale` type, improving type safety across your app.
67
67
68
-
To simplify narrowing of `string`-based locales, a `hasLocale` function has been added. This can for example be used in [`i18n/request.ts`](https://v4.next-intl.dev/docs/getting-started/app-router/with-i18n-routing#i18n-request) to return a valid locale:
68
+
To simplify narrowing of `string`-based locales, a `hasLocale` function has been added. This can for example be used in [`i18n/request.ts`](/docs/getting-started/app-router/with-i18n-routing#i18n-request) to return a valid locale:
Due to a current limitation in TypeScript, this feature is opt-in for now. Please refer to the [strict arguments](https://v4.next-intl.dev/docs/workflows/typescript#messages-arguments) docs to learn how to enable it.
151
+
Due to a current limitation in TypeScript, this feature is opt-in for now. Please refer to the [strict arguments](/docs/workflows/typescript#messages-arguments) docs to learn how to enable it.
152
152
153
153
## GDPR compliance [#gdpr-compliance]
154
154
155
155
In order to comply with the current GDPR regulations, the following changes have been made and are relevant to you if you're using the `next-intl` middleware for i18n routing:
156
156
157
-
1. The locale cookie now defaults to a session cookie that expires when a browser is closed.
157
+
1. The locale cookie now defaults to a session cookie that expires when the browser is closed.
158
158
2. The locale cookie is now only set when a user switches to a locale that doesn't match the `accept-language` header.
159
159
160
160
If you want to increase the cookie expiration, e.g. because you're informing users about the usage of cookies or if GDPR doesn't apply to your app, you can use the `maxAge` attribute to do so:
Since the cookie is now only available after a locale switch, make sure to not rely on it always being present. E.g. if you need access to the user's locale in a [Route Handler](https://v4.next-intl.dev/docs/environments/actions-metadata-route-handlers#route-handlers), a reliable option is to provide the locale as a search param (e.g. `/api/posts/12?locale=en`).
177
+
Since the cookie is now only available after a locale switch, make sure to not rely on it always being present. E.g. if you need access to the user's locale in a [Route Handler](/docs/environments/actions-metadata-route-handlers#route-handlers), a reliable option is to provide the locale as a search param (e.g. `/api/posts/12?locale=en`).
178
178
179
-
As part of this change, disabling a cookie now requires you to set [`localeCookie: false`](https://v4.next-intl.dev/docs/routing#locale-cookie) in your routing configuration. Previously, `localeDetection: false` ambiguously also disabled the cookie from being set, but since a separate `localeCookie` option was introduced recently, this should now be used instead.
179
+
As part of this change, disabling a cookie now requires you to set [`localeCookie: false`](/docs/routing#locale-cookie) in your routing configuration. Previously, `localeDetection: false` ambiguously also disabled the cookie from being set, but since a separate `localeCookie` option was introduced recently, this should now be used instead.
180
180
181
-
Learn more in the [locale cookie](https://v4.next-intl.dev/docs/routing#locale-cookie) docs.
181
+
Learn more in the [locale cookie](/docs/routing#locale-cookie) docs.
182
182
183
183
## Modernized build output
184
184
@@ -266,7 +266,7 @@ This will create the following structure:
266
266
-`example.no`: `no-NO`
267
267
-`example.no/en`: `en-NO`
268
268
269
-
Learn more in the updated docs for [`domains`](https://v4.next-intl.dev/docs/routing#domains).
269
+
Learn more in the updated docs for [`domains`](/docs/routing#domains).
270
270
271
271
## Preparation for upcoming Next.js features [#nextjs-future]
272
272
@@ -300,11 +300,9 @@ For a smooth upgrade, please initially upgrade to the latest v3.x version and ch
300
300
Afterwards, you can upgrade by running:
301
301
302
302
```
303
-
npm install next-intl@v4-beta
303
+
npm install next-intl@4
304
304
```
305
305
306
-
The beta docs are available here: [v4.next-intl.dev](https://v4.next-intl.dev)
307
-
308
306
I'd love to hear about your experiences with `next-intl@4.0`! Join the conversation in the [discussions](https://github.com/amannn/next-intl/discussions/1631).
309
307
310
308
## Thank you!
@@ -315,6 +313,8 @@ A special thank you goes to <PartnerContentLink href="https://crowdin.com/">Crow
315
313
316
314
—Jan
317
315
316
+
(this post has been updated from an initial announcement for the 3.0 release candidate)
317
+
318
318
PS: Have you heard that [learn.next-intl.dev](https://learn.next-intl.dev) is coming?
Copy file name to clipboardexpand all lines: docs/src/pages/docs/environments/actions-metadata-route-handlers.mdx
+8-2
Original file line number
Diff line number
Diff line change
@@ -173,8 +173,9 @@ Note that by default, `next-intl` returns [the `link` response header](/docs/rou
173
173
174
174
Next.js supports providing alternate URLs per language via the [`alternates` entry](https://nextjs.org/docs/app/api-reference/file-conventions/metadata/sitemap#generate-a-localized-sitemap). You can construct a list of entries for each pathname and locale as follows:
Copy file name to clipboardexpand all lines: docs/src/pages/docs/environments/error-files.mdx
+5-5
Original file line number
Diff line number
Diff line change
@@ -77,16 +77,16 @@ export default function RootLayout({children}) {
77
77
}
78
78
```
79
79
80
-
For the 404 page to render, we need to call the `notFound` function in the root layout when we detect an incoming `locale` param that isn't a valid locale.
80
+
For the 404 page to render, we need to call the `notFound` function in the root layout when we detect an incoming `locale` param that isn't valid.
Copy file name to clipboardexpand all lines: docs/src/pages/docs/environments/server-client-components.mdx
+10-14
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
82
+
// execute as a Client Component.
80
83
return (
81
84
<section>
82
85
<h2>{t('title')}</h2>
@@ -112,11 +115,13 @@ Regarding performance, async functions and hooks can be used interchangeably. Th
112
115
113
116
## Using internationalization in Client Components
114
117
115
-
Depending on your situation, you may need to handle internationalization in Client Components. While providing all messages to the client side is typically the easiest way to [get started](/docs/getting-started/app-router#layout) and a reasonable approach for many apps, you can be more selective about which messages are passed to the client side if you're interested in optimizing the performance of your app.
118
+
Depending on your situation, you may need to handle internationalization in Client Components. Providing all messages to the client side is the easiest way to get started, therefore `next-intl` automatically does this when you render [`NextIntlClientProvider`](/docs/usage/configuration#nextintlclientprovider). This is a reasonable approach for many apps.
119
+
120
+
However, you can be more selective about which messages are passed to the client side if you're interested in optimizing the performance of your app.
116
121
117
122
There are several options for using translations from `next-intl` in Client Components, listed here in order of enabling the best performance:
118
123
119
-
### Option 1: Passing translations to Client Components
124
+
### Option 1: Passing translated labels to Client Components
120
125
121
126
The preferred approach is to pass the processed labels as props or `children` from a Server Component.
122
127
@@ -275,8 +280,6 @@ In particular, page and search params are often a great option because they offe
275
280
276
281
### Option 3: Providing individual messages
277
282
278
-
To reduce bundle size, `next-intl` doesn't automatically provide [messages](/docs/usage/configuration#messages) or [formats](/docs/usage/configuration#formats) to Client Components.
279
-
280
283
If you need to incorporate dynamic state into components that can not be moved to the server side, you can wrap these components with `NextIntlClientProvider` and provide the relevant messages.
281
284
282
285
```tsx filename="Counter.tsx"
@@ -312,22 +315,16 @@ An automatic, compiler-driven approach is being evaluated in [`next-intl#1`](htt
312
315
313
316
### Option 4: Providing all messages
314
317
315
-
If you're building a highly dynamic app where most components use React's interactive features, you may prefer to make all messages available to Client Components.
318
+
If you're building a highly dynamic app where most components use React's interactive features, you may prefer to make all messages available to Client Components—this is the default behavior of `next-intl`.
0 commit comments