Skip to content

Commit 9e73cbe

Browse files
authored
feat: Validate locale returned from i18n/request.ts (#1695)
1 parent bae1131 commit 9e73cbe

File tree

5 files changed

+19
-23
lines changed

5 files changed

+19
-23
lines changed

packages/next-intl/src/routing/defineRouting.tsx

-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import type {
55
Locales,
66
Pathnames
77
} from './types.js';
8-
import validateLocales from './validateLocales.js';
98

109
export default function defineRouting<
1110
const AppLocales extends Locales,
@@ -20,8 +19,5 @@ export default function defineRouting<
2019
AppDomains
2120
>
2221
) {
23-
if (process.env.NODE_ENV !== 'production') {
24-
validateLocales(config.locales);
25-
}
2622
return config;
2723
}

packages/next-intl/src/routing/validateLocales.tsx

-16
This file was deleted.

packages/next-intl/src/server/react-server/getConfig.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
import {getRequestLocale} from './RequestLocale.js';
1010
import createRequestConfig from './createRequestConfig.js';
1111
import type {GetRequestConfigParams} from './getRequestConfig.js';
12+
import validateLocale from './validateLocale.js';
1213

1314
// This is automatically inherited by `NextIntlClientProvider` if
1415
// the component is rendered from a Server Component
@@ -60,6 +61,9 @@ See also: https://next-intl.dev/docs/usage/configuration#i18n-request
6061
'No locale was returned from `getRequestConfig`.\n\nSee https://next-intl.dev/docs/usage/configuration#i18n-request'
6162
);
6263
}
64+
if (process.env.NODE_ENV !== 'production') {
65+
validateLocale(result.locale);
66+
}
6367

6468
return result;
6569
}

packages/next-intl/src/routing/validateLocales.test.tsx packages/next-intl/src/server/react-server/validateLocale.test.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
2-
import validateLocales from './validateLocales.js';
2+
import validateLocale from './validateLocale.js';
33

44
describe('accepts valid formats', () => {
55
let consoleErrorSpy: ReturnType<typeof vi.spyOn>;
@@ -34,7 +34,7 @@ describe('accepts valid formats', () => {
3434
// Somehow tolerated by Intl.Locale
3535
'english'
3636
])('accepts: %s', (locale) => {
37-
validateLocales([locale]);
37+
validateLocale(locale);
3838
expect(consoleErrorSpy).not.toHaveBeenCalled();
3939
});
4040
});
@@ -65,7 +65,7 @@ describe('warns for invalid formats', () => {
6565
'en US',
6666
'en.US'
6767
])('rejects: %s', (locale) => {
68-
validateLocales([locale]);
68+
validateLocale(locale);
6969
expect(consoleErrorSpy).toHaveBeenCalled();
7070
});
7171
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export default function validateLocale(locale: string) {
2+
try {
3+
const constructed = new Intl.Locale(locale);
4+
if (!constructed.language) {
5+
throw new Error('Language is required');
6+
}
7+
} catch {
8+
console.error(
9+
`An invalid locale was provided: "${locale}"\nPlease ensure you're using a valid Unicode locale identifier (e.g. "en-US").`
10+
);
11+
}
12+
}

0 commit comments

Comments
 (0)