amannn / next-intl

🌐 Internationalization (i18n) for Next.js
https://next-intl-docs.vercel.app
MIT License
2.58k stars 236 forks source link

feat: Add async `requestLocale` param to `getRequestConfig` for Next.js 15 support #1383

Closed amannn closed 1 month ago

amannn commented 1 month ago

Since Next.js is switching headers() to be async, the locale that is passed to getRequestConfig needs to be replaced by an awaitable alternative. Note that this is only relevant for your app in case you're using i18n routing.

tldr;

Switch to the new API and call it a day:

export default getRequestConfig(async ({
-  locale
+  requestLocale
}) => {
+  const locale = await requestLocale;

  // ...
});

If your app worked well before, then this is a 1:1 switch and will get your app in shape for Next.js 15.

Details

The new requestLocale parameter also offered a chance to get in some enhancements for edge cases that were previously harder to support. Therefore, the following migration is generally recommended:

Before:

import {notFound} from 'next/navigation';
import {getRequestConfig} from 'next-intl/server';
import {routing} from './routing';

export default getRequestConfig(async ({locale}) => {
  // Validate that the incoming `locale` parameter is valid
  if (!routing.locales.includes(locale as any)) notFound();

  return {
    // ...
  };
});

After:

import {getRequestConfig} from 'next-intl/server';
import {routing} from './routing';

export default getRequestConfig(async ({requestLocale}) => {
  // This typically corresponds to the `[locale]` segment
  let locale = await requestLocale;

  // Ensure that the incoming locale is valid
  if (!locale || !routing.locales.includes(locale as any)) {
    locale = routing.defaultLocale;
  }

  return {
    locale,
    // ...
  };
});

The differences are:

  1. requestLocale is a promise that needs to be awaited
  2. The resolved value can be undefined—therefore a default should be supplied. The default assignment allows handling cases where an error would be thrown previously, e.g. when using APIs like useTranslations on a global language selection page at app/page.tsx.
  3. The locale should be returned (since you can now adjust it in the function body).
  4. We now recommend calling notFound() in response to an invalid [locale] param in app/[locale]/layout.tsx instead of in i18n/request.ts. This unlocks another use case, where APIs like useTranslations can now be used on a global app/not-found.tsx page.

See also the updated getting started docs.

Note that this change is non-breaking, but the synchronously available locale is now considered deprecated and will be removed in a future major version.

Contributes to https://github.com/amannn/next-intl/issues/1375 Addresses https://github.com/amannn/next-intl/discussions/1355

vercel[bot] commented 1 month ago

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
next-intl-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 2, 2024 3:56pm
next-intl-example-app-router ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 2, 2024 3:56pm
next-intl-example-app-router-without-i18n-routing ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 2, 2024 3:56pm