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
6.[**Improved inheritance in `NextIntlClientProvider`**](#nextintlclientprovider-inheritance)
22
-
7.[**Preparation for upcoming Next.js features**](#nextjs-future)
22
+
7.[**Stricter config for `domains`**](#domains-config)
23
+
8.[**Preparation for upcoming Next.js features**](#nextjs-future)
23
24
24
-
Please also have a look at the [other breaking changes](#other-breaking-changes) listed below before you upgrade.
25
+
Please also have a look at the [other changes](#other-changes) listed below before you upgrade.
25
26
26
27
## Revamped augmented types
27
28
@@ -118,7 +119,7 @@ t('message', {});
118
119
t('message', {});
119
120
// ^? {page: number, total: number}
120
121
121
-
// "You have {count, plural, =0 {no followers yet} =1 {one follower} other {# followers}}."
122
+
// "You have {count, plural, =0 {no followers yet} one {one follower} other {# followers}}."
122
123
t('message', {});
123
124
// ^? {count: number}
124
125
@@ -127,8 +128,8 @@ t('message', {});
127
128
// ^? {country: 'US' | 'CA' | (string & {})}
128
129
129
130
// "Please refer to the <link>guidelines</link>."
130
-
t('message', {});
131
-
// ^? {link: (chunks: ReactNode) => ReactNode}
131
+
t.rich('message', {});
132
+
//^? {link: (chunks: ReactNode) => ReactNode}
132
133
```
133
134
134
135
With this type inference in place, you can now use autocompletion in your IDE to get suggestions for the available arguments of a given ICU message and catch potential errors early.
@@ -153,7 +154,7 @@ Due to a current limitation in TypeScript, this feature is opt-in for now. Pleas
153
154
154
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:
155
156
156
-
1. The locale cookie has been changed 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 a browser is closed.
157
158
2. The locale cookie is now only set when a user switches to a locale that doesn't match the `accept-language` header.
158
159
159
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:
@@ -187,13 +188,13 @@ The build output of `next-intl` has been modernized and now leverages the follow
187
188
2.**Modern JSX transform:** The peer dependency for React has been bumped to v17 in order to use the more efficient, modern JSX transform.
188
189
3.**Modern syntax:** Syntax is now compiled down to the Browserslist `defaults` query, which is a shortcut for ">0.5%, last 2 versions, Firefox ESR, not dead"—a baseline that is considered a reasonable target for modern apps.
189
190
190
-
With these changes, the bundle size of `next-intl` has been reduced by ~7% ([all details](https://github.com/amannn/next-intl/pull/1470)).
191
+
With these changes, the bundle size of `next-intl` has been reduced by ~7% ([PR #1470](https://github.com/amannn/next-intl/pull/1470)).
191
192
192
193
## Improved inheritance of `NextIntlClientProvider`[#nextintlclientprovider-inheritance]
193
194
194
195
Previously, [`NextIntlClientProvider`](/docs/usage/configuration#nextintlclientprovider) would conservatively inherit only a subset from `i18n/request.ts`.
195
196
196
-
To improve the getting started experience, the provider now also inherits:
197
+
To improve the getting started experience, the provider by default now also inherits:
@@ -209,10 +210,64 @@ Due to this, you can now remove these props from `NextIntlClientProvider` if you
209
210
</NextIntlClientProvider>
210
211
```
211
212
213
+
If you don't want to inherit these props, you can either opt-out via `messages={null}` and `formats={null}`, or by passing a specific value for these props.
214
+
212
215
With this, `NextIntlClientProvider` now inherits all of your configuration, with the minor exception of [error handling functions](/docs/usage/configuration#error-handling). Since functions are not serializable, they cannot be passed across the server/client boundary. However, [an alternative](https://github.com/amannn/next-intl/issues/1285) for this is also on the horizon.
213
216
214
217
To make it easier to work with error handling functions on the client side, `NextIntlClientProvider` can now also be used in a nested fashion and will inherit the configuration from a parent provider ([PR #1413](https://github.com/amannn/next-intl/pull/1413)).
215
218
219
+
## Stricter config for `domains`[#domains-config]
220
+
221
+
So far, when using [`domains`](/docs/routing#domains) in combination with [`localePrefix: 'as-needed'`](/docs/routing#locale-prefix-as-needed), `next-intl` had to make some [tradeoffs](https://next-intl-docs-6wwcmwb9a-next-intl.vercel.app/docs/routing#domains-localeprefix-asneeded) to avoid reading the current host of the incoming request in components.
222
+
223
+
Now, by introducing two new constraints, `next-intl` can avoid these tradeoffs altogether:
224
+
225
+
1. A locale can now only be used for a single domain
226
+
2. Each domain now must specify its `locales`
227
+
228
+
The result is a simplified, more intuitive model that works as expected for this popular use case.
229
+
230
+
If you previously used locales across multiple domains, you now have to be more specific—typically by introducing a regional variant for a base language. You can additionally customize the prefixes if desired.
231
+
232
+
**Example:**
233
+
234
+
```tsx
235
+
import {defineRouting} from'next-intl/routing';
236
+
237
+
exportconst routing =defineRouting({
238
+
locales: ['sv-SE', 'en-SE', 'no-NO', 'en-NO'],
239
+
defaultLocale: 'en-SE',
240
+
localePrefix: {
241
+
mode: 'as-needed',
242
+
prefixes: {
243
+
'en-SE': '/en',
244
+
'en-NO': '/en'
245
+
}
246
+
},
247
+
domains: [
248
+
{
249
+
domain: 'example.se',
250
+
defaultLocale: 'sv-SE',
251
+
locales: ['sv-SE', 'en-SE']
252
+
},
253
+
{
254
+
domain: 'example.no',
255
+
defaultLocale: 'no-NO',
256
+
locales: ['no-NO', 'en-NO']
257
+
}
258
+
]
259
+
});
260
+
```
261
+
262
+
This will create the following structure:
263
+
264
+
-`example.se`: `sv-SE`
265
+
-`example.se/en`: `en-SE`
266
+
-`example.no`: `no-NO`
267
+
-`example.no/en`: `en-NO`
268
+
269
+
Learn more in the updated docs for [`domains`](https://v4.next-intl.dev/docs/routing#domains).
270
+
216
271
## Preparation for upcoming Next.js features [#nextjs-future]
217
272
218
273
To ensure that the sails of `next-intl` are set for a steady course in the upcoming future, I've investigated the implications of upcoming Next.js features like [`ppr`](https://nextjs.org/docs/app/api-reference/next-config-js/ppr), [`dynamicIO`](https://nextjs.org/docs/canary/app/api-reference/config/next-config-js/dynamicIO) and [`rootParams`](https://github.com/vercel/next.js/pull/72837) for `next-intl`.
@@ -221,21 +276,22 @@ This led to three minor changes:
221
276
222
277
1. If you don't already have a `NextIntlClientProvider` in your app that wraps all Client Components that use `next-intl`, you now have to add one (see [PR #1541](https://github.com/amannn/next-intl/pull/1541) for details).
223
278
2. If you're using `format.relativeTime` in Client Components, you may need to provide the `now` argument explicitly now (see [PR #1536](https://github.com/amannn/next-intl/pull/1536) for details).
224
-
3. If you're using i18n routing, make sure you've updated to [`await requestLocale`](https://next-intl.dev/blog/next-intl-3-22#await-request-locale) that was introduced in `next-intl@3.22`. The previously deprecated `locale` argument will serve an edge case in the future once `rootParams` is a thing (see [PR #1625](https://github.com/amannn/next-intl/pull/1625/) for details).
279
+
3. If you're using i18n routing, make sure you've updated to [`await requestLocale`](/blog/next-intl-3-22#await-request-locale) that was introduced in `next-intl@3.22`. The previously deprecated `locale` argument will serve an edge case in the future once `rootParams` is a thing (see [PR #1625](https://github.com/amannn/next-intl/pull/1625/) for details).
225
280
226
281
While the mentioned Next.js features are still under development and may change, these changes seem reasonable to me in any case—and ideally will be all that's necessary to adapt for `next-intl` to get the most out of these upcoming capabilities.
227
282
228
283
I'm particularly excited about the announcement of `rootParams`, as it seems like this will finally fill in the [missing piece](https://github.com/vercel/next.js/discussions/58862) that enables apps with i18n routing to support static rendering without workarounds like `setRequestLocale`. I hope to have more to share on this soon!
229
284
230
-
## Other breaking changes
285
+
## Other changes
231
286
232
287
1. Return type-safe messages from `useMessages` and `getMessages` (see [PR #1489](https://github.com/amannn/next-intl/pull/1489))
233
288
2. Require locale to be returned from `getRequestConfig` (see [PR #1486](https://github.com/amannn/next-intl/pull/1486))
234
-
3. Disallow passing `null`, `undefined` or `boolean` as an ICU argument (see [PR #1561](https://github.com/amannn/next-intl/pull/1561))
235
-
4. Bump minimum required TypeScript version to 5 for projects using TypeScript (see [PR #1481](https://github.com/amannn/next-intl/pull/1481))
236
-
5. Return `x-default` alternate link also for sub pages when using `localePrefix: 'always'` and update middleware matcher suggestion in docs (see [PR #1720](https://github.com/amannn/next-intl/pull/1720))
237
-
6. Remove deprecated APIs (see [PR #1479](https://github.com/amannn/next-intl/pull/1479))
238
-
7. Remove deprecated APIs pt. 2 (see [PR #1482](https://github.com/amannn/next-intl/pull/1482))
289
+
3. Allow to declare `pathnames` partially for convenience (see [PR #1743](https://github.com/amannn/next-intl/pull/1743))
290
+
4. Disallow passing `null`, `undefined` or `boolean` as an ICU argument (see [PR #1561](https://github.com/amannn/next-intl/pull/1561))
291
+
5. Bump minimum required TypeScript version to 5 for projects using TypeScript (see [PR #1481](https://github.com/amannn/next-intl/pull/1481))
292
+
6. Return `x-default` alternate link also for sub pages when using `localePrefix: 'always'` and update middleware matcher suggestion to `/((?!api|_next|_vercel|.*\\..*).*)` (see [PR #1720](https://github.com/amannn/next-intl/pull/1720))
293
+
7. Remove deprecated APIs (see [PR #1479](https://github.com/amannn/next-intl/pull/1479))
294
+
8. Remove deprecated APIs pt. 2 (see [PR #1482](https://github.com/amannn/next-intl/pull/1482))
239
295
240
296
## Upgrade now
241
297
@@ -255,7 +311,7 @@ I'd love to hear about your experiences with `next-intl@4.0`! Join the conversat
255
311
256
312
I want to sincerely thank everyone who has helped to make `next-intl` what it is today.
257
313
258
-
A special thank you goes to <PartnerContentLinkhref="https://crowdin.com/">Crowdin</PartnerContentLink>, the primary sponsor of `next-intl`, enabling me to regularly work on this project and provide it as a free and open-source library for everyone.
314
+
A special thank you goes to <PartnerContentLinkhref="https://crowdin.com/">Crowdin</PartnerContentLink>, the sponsor partner of `next-intl`, enabling me to regularly work on this project and provide it as a free and open-source library for everyone.
0 commit comments