Skip to content

Commit

Permalink
fix: Resolve locale for navigation APIs consistently from `i18n/reque…
Browse files Browse the repository at this point in the history
…st.ts` in `react-server` like all other APIs do (#1459)
  • Loading branch information
amannn authored Oct 24, 2024
1 parent 5d60cdf commit 8c6d5ff
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 16 deletions.
21 changes: 15 additions & 6 deletions docs/src/pages/docs/routing/middleware.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -432,14 +432,23 @@ export default function RootPage() {

## Troubleshooting

### "Unable to find `next-intl` locale because the middleware didn't run on this request and no `locale` was returned in `getRequestConfig`." [#unable-to-find-locale]

If the middleware is not expected to run on this request (e.g. because you're using a setup [without i18n routing](/docs/getting-started/app-router/without-i18n-routing)), you should explicitly return a `locale` from [`getRequestConfig`](/docs/usage/configuration#i18n-request) to recover from this error.
### "The middleware doesn't run for a particular page." [#middleware-not-running]

If the error occurs for pathnames where the middleware is expected to run, please make sure that:
To resolve this, make sure that:

1. The middleware is set up in the correct file (e.g. `src/middleware.ts`).
1. The [middleware](/docs/getting-started/app-router/with-i18n-routing#middleware) is set up in the correct file (e.g. `src/middleware.ts`).
2. Your middleware [matcher](#matcher-config) correctly matches all routes of your application, including dynamic segments with potentially unexpected characters like dots (e.g. `/users/jane.doe`).
3. In case you require static rendering, make sure to follow the [static rendering guide](/docs/getting-started/app-router/with-i18n-routing#static-rendering) instead of relying on hacks like [`force-static`](https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamic).
3. In case you're [composing other middlewares](#composing-other-middlewares), ensure that the middleware is called correctly.
4. In case you require static rendering, make sure to follow the [static rendering guide](/docs/getting-started/app-router/with-i18n-routing#static-rendering) instead of relying on hacks like [`force-static`](https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamic).

### "My page content isn't localized despite the pathname containing a locale prefix." [#content-not-localized]

This is very likely the result of your [middleware not running](#middleware-not-running) on the request. As a result, a potential fallback from [`i18n/request.ts`](/docs/usage/configuration#i18n-request) might be applied.

### "Unable to find `next-intl` locale because the middleware didn't run on this request and no `locale` was returned in `getRequestConfig`." [#unable-to-find-locale]

If the middleware _is not_ expected to run on this request (e.g. because you're using a setup [without i18n routing](/docs/getting-started/app-router/without-i18n-routing)), you should explicitly return a `locale` from [`getRequestConfig`](/docs/usage/configuration#i18n-request) to recover from this error.

If the middleware _is_ expected to run, verify that your [middleware is set up correctly](#middleware-not-running).

Note that `next-intl` will invoke the `notFound()` function to abort the render if no locale is available after `getRequestConfig` has run. You should consider adding a [`not-found` page](/docs/environments/error-files#not-foundjs) due to this.
2 changes: 1 addition & 1 deletion docs/src/pages/docs/workflows/typescript.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ declare global {

## Troubleshooting

If you're encountering problems, please double check that:
If you're encountering problems, double check that:

1. Your interface uses the correct name.
2. You're using TypeScript version 4 or later.
Expand Down
2 changes: 1 addition & 1 deletion packages/next-intl/.size-limit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const config: SizeLimitConfig = [
name: "import {createSharedPathnamesNavigation} from 'next-intl/navigation' (react-server)",
path: 'dist/production/navigation.react-server.js',
import: '{createSharedPathnamesNavigation}',
limit: '16.765 KB'
limit: '16.77 KB'
},
{
name: "import {createLocalizedPathnamesNavigation} from 'next-intl/navigation' (react-server)",
Expand Down
13 changes: 7 additions & 6 deletions packages/next-intl/src/navigation/createNavigation.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import React from 'react';
import {renderToString} from 'react-dom/server';
import {beforeEach, describe, expect, it, vi} from 'vitest';
import {DomainsConfig, Pathnames, defineRouting} from '../routing';
import {getRequestLocale} from '../server/react-server/RequestLocale';
import createNavigationClient from './react-client/createNavigation';
import createNavigationServer from './react-server/createNavigation';
import getServerLocale from './react-server/getServerLocale';

vi.mock('react');
vi.mock('next/navigation', async () => {
Expand All @@ -23,15 +23,16 @@ vi.mock('next/navigation', async () => {
permanentRedirect: vi.fn()
};
});
vi.mock('../../src/server/react-server/RequestLocale');
vi.mock('./react-server/getServerLocale');

function mockCurrentLocale(locale: string) {
// Enable synchronous rendering without having to suspend
const localePromise = Promise.resolve(locale);
(localePromise as any).status = 'fulfilled';
(localePromise as any).value = locale;
const value = locale;
const promise = Promise.resolve(value);
(promise as any).status = 'fulfilled';
(promise as any).value = value;

vi.mocked(getRequestLocale).mockImplementation(() => localePromise);
vi.mocked(getServerLocale).mockImplementation(() => promise);

vi.mocked(nextUseParams<{locale: string}>).mockImplementation(() => ({
locale
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import {
Locales,
Pathnames
} from '../../routing/types';
import {getRequestLocale} from '../../server/react-server/RequestLocale';
import createSharedNavigationFns from '../shared/createSharedNavigationFns';
import getServerLocale from './getServerLocale';

export default function createNavigation<
const AppLocales extends Locales,
Expand All @@ -35,7 +35,7 @@ export default function createNavigation<
type Locale = AppLocales extends never ? string : AppLocales[number];

function getLocale() {
return getRequestLocale() as Promise<Locale>;
return getServerLocale() as Promise<Locale>;
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
Expand Down
10 changes: 10 additions & 0 deletions packages/next-intl/src/navigation/react-server/getServerLocale.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import getConfig from '../../server/react-server/getConfig';

/**
* This is only moved to a separate module for easier mocking in
* `../createNavigatoin.test.tsx` in order to avoid suspending.
*/
export default async function getServerLocale() {
const config = await getConfig();
return config.locale;
}

0 comments on commit 8c6d5ff

Please sign in to comment.