Skip to content

Commit c332633

Browse files
blechatellierQuiiBz
andauthoredOct 28, 2024··
feat: support next@15 (#426)
Co-authored-by: Tom Lienard <[email protected]>
1 parent a049386 commit c332633

File tree

14 files changed

+415
-148
lines changed

14 files changed

+415
-148
lines changed
 

‎docs/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"dependencies": {
1212
"@vercel/analytics": "^1.1.1",
1313
"@vercel/speed-insights": "^1.0.2",
14-
"next": "^14.0.4",
14+
"next": "^15.0.0",
1515
"nextra": "^2.13.2",
1616
"nextra-theme-docs": "^2.13.2",
1717
"react": "^18.2.0",

‎docs/pages/docs/app-setup.mdx

+5-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@ Move all your routes inside an `app/[locale]/` folder. For Client Components, wr
5151
import { ReactElement } from 'react'
5252
import { I18nProviderClient } from '../../locales/client'
5353

54-
export default function SubLayout({ params: { locale }, children }: { params: { locale: string }, children: ReactElement }) {
54+
// If you are using Next.js < 15, you don't need to await `params`:
55+
// export default function SubLayout({ params: { locale }, children }: { params: { locale: string }, children: ReactElement }) {
56+
export default function SubLayout({ params, children }: { params: Promise<{ locale: string }>, children: ReactElement }) {
57+
const { locale } = await params
58+
5559
return (
5660
<I18nProviderClient locale={locale}>
5761
{children}

‎docs/pages/docs/app-static-rendering.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ Inside all pages that you want to be statically rendered, call this `setStaticPa
2222
// app/[locale]/page.tsx and any other page
2323
import { setStaticParamsLocale } from 'next-international/server'
2424

25-
export default function Page({ params: { locale } }: { params: { locale: string } }) {
25+
// If you are using Next.js < 15, you don't need to await `params`:
26+
// export default function Page({ params: { locale } }: { params: { locale: string } }) {
27+
export default function Page({ params }: { params: Promise<{ locale: string }> }) {
28+
const { locale } = await params
2629
setStaticParamsLocale(locale)
2730

2831
return (

‎docs/pages/docs/rtl-support.mdx

+9-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ If you want to support the `dir` attribute in your `<html>` tag, you'll need to
88

99
```tsx {3,6}
1010
// app/[locale]/layout.tsx
11-
export default function Layout({ children, params: { locale } }: { children: ReactElement, params: { locale: string } }) {
11+
12+
// If you are using Next.js < 15, you don't need to await `params`:
13+
// export default function Layout({ children, params: { locale } }: { children: ReactElement, params: { locale: string } }) {
14+
export default function Layout({ children, params }: { children: ReactElement, params: Promise<{ locale: string }> }) {
15+
const { locale } = await params
1216
const dir = new Intl.Locale(locale).getTextInfo().direction
1317

1418
return (
@@ -56,7 +60,10 @@ Then, use it instead of the native `Intl.Locale.prototype.getTextInfo` API:
5660
// app/[locale]/layout.tsx
5761
import Locale from 'intl-locale-textinfo-polyfill'
5862

59-
export default function Layout({ children, params: { locale } }: { children: ReactElement, params: { locale: string } }) {
63+
// If you are using Next.js < 15, you don't need to await `params`:
64+
// export default function Layout({ children, params: { locale } }: { children: ReactElement, params: { locale: string } }) {
65+
export default function Layout({ children, params }: { children: ReactElement, params: Promise<{ locale: string }> }) {
66+
const { locale } = await params
6067
const { direction: dir } = new Locale(locale).textInfo
6168

6269
return (
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
import type { ReactNode } from 'react';
22
import { Provider } from '../provider';
33

4-
export default function Layout({ params: { locale }, children }: { params: { locale: string }; children: ReactNode }) {
4+
export default async function Layout({
5+
params,
6+
children,
7+
}: {
8+
params: Promise<{ locale: string }>;
9+
children: ReactNode;
10+
}) {
11+
const { locale } = await params;
12+
513
return <Provider locale={locale}>{children}</Provider>;
614
}

‎examples/next-app/app/[locale]/page.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import { Provider } from './provider';
99
// }
1010

1111
// eslint-disable-next-line @typescript-eslint/no-unused-vars
12-
export default async function Home({ params: { locale } }: { params: { locale: string } }) {
12+
export default async function Home({ params }: { params: Promise<{ locale: string }> }) {
13+
const { locale } = await params;
14+
1315
// Uncomment to test Static Generation
1416
// setStaticParamsLocale(locale);
1517

‎examples/next-app/app/[locale]/subpage/page.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ import { getI18n } from '../../../locales/server';
77
// }
88

99
// eslint-disable-next-line @typescript-eslint/no-unused-vars
10-
export default async function Subpage({ params: { locale } }: { params: { locale: string } }) {
10+
export default async function Subpage({ params }: { params: Promise<{ locale: string }> }) {
1111
// Uncomment to test Static Generation
12+
// const { locale } = await params;
1213
// setStaticParamsLocale(locale);
1314

1415
const t = await getI18n();

‎examples/next-app/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"lint": "next lint"
1010
},
1111
"dependencies": {
12-
"next": "^14.0.4",
12+
"next": "^15.0.0",
1313
"next-international": "workspace:*",
1414
"react": "^18.2.0",
1515
"react-dom": "^18.2.0"

‎examples/next-pages/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"lint": "next lint"
1010
},
1111
"dependencies": {
12-
"next": "^14.0.4",
12+
"next": "^15.0.0",
1313
"next-international": "workspace:*",
1414
"react": "^18.2.0",
1515
"react-dom": "^18.2.0"

‎packages/next-international/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "next-international",
3-
"version": "1.2.4",
3+
"version": "1.3.0",
44
"description": "Type-safe internationalization (i18n) for Next.js",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",
@@ -50,7 +50,7 @@
5050
},
5151
"devDependencies": {
5252
"@types/react": "^18.2.45",
53-
"next": "^14.0.4",
53+
"next": "^15.0.0",
5454
"react": "^18.2.0",
5555
"tsup": "^8.0.1"
5656
},

‎packages/next-international/src/app/server/create-get-i18n.ts

+16-13
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,30 @@ export function createGetI18n<Locales extends ImportedLocales, Locale extends Ba
88
locales: Locales,
99
config: I18nServerConfig,
1010
) {
11-
const localeCache = new Map<string, ReturnType<typeof createT<Locale, undefined>>>();
11+
const localeCache = new Map<string, Promise<ReturnType<typeof createT<Locale, undefined>>>>();
1212

1313
return async function getI18n() {
14-
const locale = getLocaleCache();
14+
const locale = await getLocaleCache();
1515
const cached = localeCache.get(locale);
1616

1717
if (cached) {
18-
return cached;
18+
return await cached;
1919
}
2020

21-
const localeFn = createT(
22-
{
23-
localeContent: flattenLocale((await locales[locale]()).default),
24-
fallbackLocale: config.fallbackLocale ? flattenLocale(config.fallbackLocale) : undefined,
25-
locale,
26-
} as LocaleContext<Locale>,
27-
undefined,
28-
);
21+
const localeFnPromise = (async () => {
22+
const localeModule = await locales[locale]();
23+
return createT(
24+
{
25+
localeContent: flattenLocale(localeModule.default),
26+
fallbackLocale: config.fallbackLocale ? flattenLocale(config.fallbackLocale) : undefined,
27+
locale,
28+
} as LocaleContext<Locale>,
29+
undefined,
30+
);
31+
})();
2932

30-
localeCache.set(locale, localeFn);
33+
localeCache.set(locale, localeFnPromise);
3134

32-
return localeFn;
35+
return await localeFnPromise;
3336
};
3437
}

‎packages/next-international/src/app/server/create-get-scoped-i18n.ts

+16-13
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,33 @@ export function createGetScopedI18n<Locales extends ImportedLocales, Locale exte
88
locales: Locales,
99
config: I18nServerConfig,
1010
) {
11-
const localeCache = new Map<string, ReturnType<typeof createT<Locale, undefined>>>();
11+
const localeCache = new Map<string, Promise<ReturnType<typeof createT<Locale, undefined>>>>();
1212

1313
return async function getScopedI18n<Scope extends Scopes<Locale>>(
1414
scope: Scope,
1515
): Promise<ReturnType<typeof createT<Locale, Scope>>> {
16-
const locale = getLocaleCache();
16+
const locale = await getLocaleCache();
1717
const cacheKey = `${locale}-${scope}`;
1818
const cached = localeCache.get(cacheKey);
1919

2020
if (cached) {
21-
return cached;
21+
return (await cached) as ReturnType<typeof createT<Locale, Scope>>;
2222
}
2323

24-
const localeFn = createT(
25-
{
26-
localeContent: flattenLocale((await locales[locale]()).default),
27-
fallbackLocale: config.fallbackLocale ? flattenLocale(config.fallbackLocale) : undefined,
28-
locale,
29-
} as LocaleContext<Locale>,
30-
scope,
31-
);
24+
const localeFnPromise = (async () => {
25+
const localeModule = await locales[locale]();
26+
return createT(
27+
{
28+
localeContent: flattenLocale(localeModule.default),
29+
fallbackLocale: config.fallbackLocale ? flattenLocale(config.fallbackLocale) : undefined,
30+
locale,
31+
} as LocaleContext<Locale>,
32+
scope,
33+
);
34+
})();
3235

33-
localeCache.set(cacheKey, localeFn);
36+
localeCache.set(cacheKey, localeFnPromise);
3437

35-
return localeFn;
38+
return await localeFnPromise;
3639
};
3740
}

‎packages/next-international/src/app/server/get-locale-cache.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,17 @@ export const setStaticParamsLocale = (value: string) => {
1212
getLocale().current = value;
1313
};
1414

15-
export const getLocaleCache = cache(() => {
15+
export const getLocaleCache = cache(async () => {
1616
let locale: string | undefined | null;
1717

1818
locale = getStaticParamsLocale();
1919

2020
if (!locale) {
2121
try {
22-
locale = headers().get(LOCALE_HEADER);
22+
locale = (await headers()).get(LOCALE_HEADER);
2323

2424
if (!locale) {
25-
locale = cookies().get(LOCALE_COOKIE)?.value;
25+
locale = (await cookies()).get(LOCALE_COOKIE)?.value;
2626
}
2727
} catch (e) {
2828
throw new Error(

‎pnpm-lock.yaml

+343-107
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
Please sign in to comment.