diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 48ee27b72..0c3398a42 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -29,9 +29,8 @@ body:
label: Mandatory reproduction URL (CodeSandbox or GitHub repository)
description: |
**Templates:**
- - [CodeSandbox (`app` directory)](https://codesandbox.io/p/sandbox/next-intl-bug-template-forked-yow8ep)
- - [CodeSandbox (`app` directory, RSC beta)](https://codesandbox.io/p/sandbox/next-intl-bug-template-app-forked-zcymvq)
- - [CodeSandbox (`pages` directory)](https://codesandbox.io/p/sandbox/next-intl-bug-template-pages-krm37f)
+ - [CodeSandbox (App Router)](https://codesandbox.io/p/sandbox/next-intl-bug-template-app-forked-zcymvq)
+ - [CodeSandbox (Pages Router)](https://codesandbox.io/p/sandbox/next-intl-bug-template-pages-krm37f)
validations:
required: true
- type: textarea
diff --git a/docs/components/CodeSnippets.tsx b/docs/components/CodeSnippets.tsx
index afbc76ec2..246546186 100644
--- a/docs/components/CodeSnippets.tsx
+++ b/docs/components/CodeSnippets.tsx
@@ -348,7 +348,7 @@ function buildOutput() {
kB
{' '}
- 104 kB
+ 87.6 kB
@@ -358,7 +358,7 @@ function buildOutput() {
B
{' '}
- 97.5 kB
+ 80.2 kB
@@ -368,7 +368,7 @@ function buildOutput() {
kB
{' '}
- 106 kB
+ 89.3 kB
diff --git a/docs/components/VersionTabs.tsx b/docs/components/VersionTabs.tsx
deleted file mode 100644
index 8f1f4377b..000000000
--- a/docs/components/VersionTabs.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import {Tabs} from 'nextra-theme-docs';
-import {ReactNode} from 'react';
-import Chip from './Chip';
-
-type Props = {
- children: ReactNode;
- defaultLabel?: ReactNode;
- rscLabel?: ReactNode;
-};
-
-export default function VersionTabs({
- children,
- defaultLabel = 'Default',
- rscLabel = 'Server Components'
-}: Props) {
- return (
-
This is raw HTML
" } diff --git a/docs/pages/docs/usage/numbers.mdx b/docs/pages/docs/usage/numbers.mdx index 174a693fc..0c0f74600 100644 --- a/docs/pages/docs/usage/numbers.mdx +++ b/docs/pages/docs/usage/numbers.mdx @@ -77,6 +77,6 @@ t(- {t('Index.title')} {intl.formatRelativeTime(tomorrow)} + {t('Index.title')} {format.relativeTime(tomorrow)}
); } diff --git a/examples/example-next-13-advanced/src/middleware.ts b/examples/example-next-13-advanced/src/middleware.ts index b5529e52b..4006e7a92 100644 --- a/examples/example-next-13-advanced/src/middleware.ts +++ b/examples/example-next-13-advanced/src/middleware.ts @@ -3,6 +3,7 @@ import {locales, pathnames} from './navigation'; export default createMiddleware({ defaultLocale: 'en', + localePrefix: 'as-needed', pathnames, locales }); diff --git a/examples/example-next-13-next-auth/src/components/LocaleSwitcher.tsx b/examples/example-next-13-next-auth/src/components/LocaleSwitcher.tsx index b36e8d373..3e31beb45 100644 --- a/examples/example-next-13-next-auth/src/components/LocaleSwitcher.tsx +++ b/examples/example-next-13-next-auth/src/components/LocaleSwitcher.tsx @@ -1,6 +1,5 @@ import {useLocale, useTranslations} from 'next-intl'; -import {usePathname} from 'next-intl/client'; -import Link from 'next-intl/link'; +import {Link, usePathname} from '../navigation'; export default function LocaleSwitcher() { const t = useTranslations('LocaleSwitcher'); diff --git a/examples/example-next-13-next-auth/src/middleware.tsx b/examples/example-next-13-next-auth/src/middleware.tsx index 21c8605fb..fb6202ee5 100644 --- a/examples/example-next-13-next-auth/src/middleware.tsx +++ b/examples/example-next-13-next-auth/src/middleware.tsx @@ -1,8 +1,8 @@ import {NextRequest} from 'next/server'; import {withAuth} from 'next-auth/middleware'; import createIntlMiddleware from 'next-intl/middleware'; +import {locales} from './navigation'; -const locales = ['en', 'de']; const publicPages = [ '/', '/login' @@ -11,6 +11,7 @@ const publicPages = [ const intlMiddleware = createIntlMiddleware({ locales, + localePrefix: 'as-needed', defaultLocale: 'en' }); diff --git a/examples/example-next-13-next-auth/src/navigation.ts b/examples/example-next-13-next-auth/src/navigation.ts new file mode 100644 index 000000000..aa71dd13d --- /dev/null +++ b/examples/example-next-13-next-auth/src/navigation.ts @@ -0,0 +1,5 @@ +import {createSharedPathnamesNavigation} from 'next-intl/navigation'; + +export const locales = ['en', 'de'] as const; +export const {Link, redirect, usePathname, useRouter} = + createSharedPathnamesNavigation({locales}); diff --git a/examples/example-next-13-with-pages/src/app/[locale]/page.tsx b/examples/example-next-13-with-pages/src/app/[locale]/page.tsx index aa0154f71..131116dc4 100644 --- a/examples/example-next-13-with-pages/src/app/[locale]/page.tsx +++ b/examples/example-next-13-with-pages/src/app/[locale]/page.tsx @@ -1,7 +1,7 @@ import {useLocale, useTranslations} from 'next-intl'; -import Link from 'next-intl/link'; import LocaleSwitcher from '../../components/LocaleSwitcher'; import PageLayout from '../../components/PageLayout'; +import {Link} from '../../navigation'; export default function Index() { const t = useTranslations('Index'); @@ -12,7 +12,7 @@ export default function Index() {{t('description')}
- + {t('navigateToAbout')}
diff --git a/examples/example-next-13-with-pages/src/middleware.ts b/examples/example-next-13-with-pages/src/middleware.ts index 8675074bb..76a4688cc 100644 --- a/examples/example-next-13-with-pages/src/middleware.ts +++ b/examples/example-next-13-with-pages/src/middleware.ts @@ -1,7 +1,8 @@ import createMiddleware from 'next-intl/middleware'; +import {locales} from './navigation'; export default createMiddleware({ - locales: ['en', 'de'], + locales, defaultLocale: 'en' }); diff --git a/examples/example-next-13-with-pages/src/navigation.ts b/examples/example-next-13-with-pages/src/navigation.ts new file mode 100644 index 000000000..aa71dd13d --- /dev/null +++ b/examples/example-next-13-with-pages/src/navigation.ts @@ -0,0 +1,5 @@ +import {createSharedPathnamesNavigation} from 'next-intl/navigation'; + +export const locales = ['en', 'de'] as const; +export const {Link, redirect, usePathname, useRouter} = + createSharedPathnamesNavigation({locales}); diff --git a/examples/example-next-13-with-pages/src/pages/_app.tsx b/examples/example-next-13-with-pages/src/pages/_app.tsx index 70f6ad26b..30ecd482b 100644 --- a/examples/example-next-13-with-pages/src/pages/_app.tsx +++ b/examples/example-next-13-with-pages/src/pages/_app.tsx @@ -1,6 +1,6 @@ import {AppProps} from 'next/app'; import {NextRouter, withRouter} from 'next/router'; -import {NextIntlProvider} from 'next-intl'; +import {NextIntlClientProvider} from 'next-intl'; type Props = AppProps & { router: NextRouter; @@ -8,12 +8,12 @@ type Props = AppProps & { function App({Component, pageProps, router}: Props) { return ( -Auch das Routing ist internationalisiert.
Wenn du die Standardsprache Englisch verwendest, siehst du /about
in der Adressleiste des Browsers auf dieser Seite.
Wenn du die Sprache auf Deutsch änderst, wird die URL mit der Locale ergänzt und lokalisiert (/de/über
).
Auch das Routing ist internationalisiert.
Wenn du die Standardsprache Englisch verwendest, siehst du /en/about
in der Adressleiste des Browsers auf dieser Seite.
Wenn du die Sprache auf Deutsch änderst, wird die URL mit der entsprechend lokalisiert (/de/über
).
The routing is internationalized too.
If you're using the default language English, you'll see /about
in the browser address bar on this page.
If you change the locale to German, the URL is prefixed with the locale and localized accordingly (/de/über
).
The routing is internationalized too.
If you're using the default language English, you'll see /en/about
in the browser address bar on this page.
If you change the locale to German, the URL is localized accordingly (/de/über
).
{chunks}
, code: (chunks) => ( diff --git a/examples/example-next-13/src/app/[locale]/layout.tsx b/examples/example-next-13/src/app/[locale]/layout.tsx index 8071055c7..63d9a2d1e 100644 --- a/examples/example-next-13/src/app/[locale]/layout.tsx +++ b/examples/example-next-13/src/app/[locale]/layout.tsx @@ -32,8 +32,7 @@ export default async function LocaleLayout({ params: {locale} }: Props) { // Validate that the incoming `locale` parameter is valid - const isValidLocale = locales.some((cur) => cur === locale); - if (!isValidLocale) notFound(); + if (!locales.includes(locale as any)) notFound(); unstable_setRequestLocale(locale); return ( diff --git a/examples/example-next-13/src/middleware.ts b/examples/example-next-13/src/middleware.ts index dde608338..b3627145a 100644 --- a/examples/example-next-13/src/middleware.ts +++ b/examples/example-next-13/src/middleware.ts @@ -8,6 +8,6 @@ export default createMiddleware({ }); export const config = { - // Skip all paths that should not be internationalized - matcher: ['/((?!api|_next|.*\\..*).*)'] + // Match only internationalized pathnames + matcher: ['/', '/(de|en)/:path*'] }; diff --git a/examples/example-next-13/tests/main.spec.ts b/examples/example-next-13/tests/main.spec.ts index 523eae149..2cd9e7b7c 100644 --- a/examples/example-next-13/tests/main.spec.ts +++ b/examples/example-next-13/tests/main.spec.ts @@ -2,7 +2,7 @@ import {test as it, expect} from '@playwright/test'; it('handles i18n routing', async ({page}) => { await page.goto('/'); - await expect(page).toHaveURL('/'); + await expect(page).toHaveURL('/en'); // A cookie remembers the last locale await page.goto('/de'); @@ -12,7 +12,7 @@ it('handles i18n routing', async ({page}) => { .getByRole('combobox', {name: 'Sprache ändern'}) .selectOption({label: 'Englisch'}); - await expect(page).toHaveURL('/'); + await expect(page).toHaveURL('/en'); page.getByRole('heading', {name: 'next-intl example'}); }); @@ -34,7 +34,7 @@ it("handles not found pages for routes that don't match the middleware", async ( }); it('sets caching headers', async ({request}) => { - for (const pathname of ['/', '/about', '/de', '/de/ueber']) { + for (const pathname of ['/en', '/en/about', '/de', '/de/ueber']) { expect((await request.get(pathname)).headers()['cache-control']).toBe( 's-maxage=31536000, stale-while-revalidate' ); @@ -58,7 +58,7 @@ it('can be used to localize the page', async ({page}) => { }); it('sets a cookie', async ({page}) => { - const response = await page.goto('/'); + const response = await page.goto('/en'); const value = await response?.headerValue('set-cookie'); expect(value).toContain('NEXT_LOCALE=en;'); expect(value).toContain('Path=/;'); diff --git a/packages/next-intl/link.d.ts b/packages/next-intl/link.d.ts deleted file mode 100644 index ea51c91da..000000000 --- a/packages/next-intl/link.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import Link from './dist/types/src/link'; - -export = Link; diff --git a/packages/next-intl/package.json b/packages/next-intl/package.json index 0e344793e..496a20339 100644 --- a/packages/next-intl/package.json +++ b/packages/next-intl/package.json @@ -32,15 +32,6 @@ "react-server": "./dist/esm/server.react-server.js", "default": "./dist/server.js" }, - "./client": { - "types": "./client.d.ts", - "default": "./dist/client.js" - }, - "./link": { - "types": "./link.d.ts", - "react-server": "./dist/esm/link.react-server.js", - "default": "./dist/link.js" - }, "./config": { "types": "./config.d.ts", "default": "./dist/config.js" @@ -54,7 +45,6 @@ "react-server": "./dist/esm/navigation.react-server.js", "default": "./dist/navigation.js" }, - "./withNextIntl": "./withNextIntl.js", "./plugin": { "types": "./plugin.d.ts", "default": "./dist/plugin.js" @@ -63,12 +53,8 @@ "files": [ "dist", "server.d.ts", - "client.d.ts", "navigation.d.ts", - "link.d.ts", "middleware.d.ts", - "withNextIntl.js", - "withNextIntl.d.ts", "plugin.d.ts", "config.d.ts" ], @@ -118,24 +104,16 @@ "size-limit": [ { "path": "dist/production/index.js", - "limit": "13.65 KB" + "limit": "12.7 KB" }, { "path": "dist/production/navigation.js", - "limit": "2.5 KB" + "limit": "2.6 KB" }, { "path": "dist/production/server.js", "limit": "1.3 KB" }, - { - "path": "dist/production/client.js", - "limit": "1.8 KB" - }, - { - "path": "dist/production/link.js", - "limit": "1.4 KB" - }, { "path": "dist/production/middleware.js", "limit": "5.9 KB" diff --git a/packages/next-intl/rollup.config.js b/packages/next-intl/rollup.config.js index 3268cfe60..1e9f90dff 100644 --- a/packages/next-intl/rollup.config.js +++ b/packages/next-intl/rollup.config.js @@ -7,16 +7,12 @@ const config = { index: 'src/index.tsx', 'index.react-server': 'src/index.react-server.tsx', - link: 'src/link.tsx', - 'link.react-server': 'src/link.react-server.tsx', - navigation: 'src/navigation.tsx', 'navigation.react-server': 'src/navigation.react-server.tsx', server: 'src/server.tsx', 'server.react-server': 'src/server.react-server.tsx', - client: 'src/client.tsx', middleware: 'src/middleware.tsx', plugin: 'src/plugin.tsx', config: 'src/config.tsx' diff --git a/packages/next-intl/src/client.tsx b/packages/next-intl/src/client.tsx deleted file mode 100644 index 40a7340d3..000000000 --- a/packages/next-intl/src/client.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './client/index'; diff --git a/packages/next-intl/src/client/NextIntlClientProvider.tsx b/packages/next-intl/src/client/NextIntlClientProvider.tsx deleted file mode 100644 index d63924fff..000000000 --- a/packages/next-intl/src/client/NextIntlClientProvider.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React, {ComponentProps} from 'react'; -import NextIntlClientProvider_ from '../shared/NextIntlClientProvider'; - -let hasWarned = false; -/** @deprecated Should be imported from `next-intl`, not `next-intl/client`. */ -export default function NextIntlClientProvider( - props: ComponentProps