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

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

Merged
merged 85 commits into from
Oct 2, 2024

Conversation

amannn
Copy link
Owner

@amannn amannn commented Sep 30, 2024

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 #1375
Addresses #1355

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant