Skip to content

Commit d5e4ea4

Browse files
committed
Provide example with test
1 parent 7b858bd commit d5e4ea4

File tree

18 files changed

+376
-14
lines changed

18 files changed

+376
-14
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module.exports = {
2+
env: {
3+
node: true
4+
},
5+
extends: [
6+
'molindo/typescript',
7+
'molindo/react',
8+
'plugin:@next/next/recommended'
9+
]
10+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/node_modules
2+
/.next/
3+
.DS_Store
4+
tsconfig.tsbuildinfo
5+
/test-results/
6+
/playwright-report/
7+
/playwright/.cache/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# example-app-router-provided-locale
2+
3+
An example that showcases how an app can provide a locale in `i18n.ts` to `next-intl` in an App Router setup. This can be used for single-language setups and apps where the locale is read from the user settings instead of the pathname.
4+
5+
**Note that:**
6+
7+
1. No middleware needs to be configured.
8+
2. The navigation APIs from `next-intl` don't need to be used.
9+
10+
## Deploy your own
11+
12+
By deploying to [Vercel](https://vercel.com), you can check out the example in action. Note that you'll be prompted to create a new GitHub repository as part of this, allowing you to make subsequent changes.
13+
14+
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/amannn/next-intl/tree/main/examples/example-app-router-provided-locale)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"Index": {
3+
"title": "Start",
4+
"description": "Das ist die Startseite.",
5+
"navigateToAbout": "Zu Über uns navigieren"
6+
},
7+
"About": {
8+
"title": "Über",
9+
"description": "Das ist die Über-uns-Seite."
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"Index": {
3+
"title": "Home",
4+
"description": "This is the home page.",
5+
"navigateToAbout": "Navigate to about"
6+
},
7+
"About": {
8+
"title": "About",
9+
"description": "This is the about page."
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/// <reference types="next" />
2+
/// <reference types="next/image-types/global" />
3+
4+
// NOTE: This file should not be edited
5+
// see https://nextjs.org/docs/basic-features/typescript for more information.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const withNextIntl = require('next-intl/plugin')();
2+
3+
module.exports = withNextIntl();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "example-app-router-provided-locale",
3+
"version": "2.10.2",
4+
"private": true,
5+
"scripts": {
6+
"dev": "next dev",
7+
"lint": "eslint src && tsc",
8+
"test": "playwright test",
9+
"build": "next build",
10+
"start": "next start"
11+
},
12+
"dependencies": {
13+
"next": "^14.2.1",
14+
"next-intl": "latest",
15+
"react": "^18.2.0",
16+
"react-dom": "^18.2.0"
17+
},
18+
"devDependencies": {
19+
"@types/lodash": "^4.14.176",
20+
"@types/node": "^20.1.2",
21+
"@types/react": "^18.2.29",
22+
"@playwright/test": "^1.41.2",
23+
"eslint": "^8.54.0",
24+
"eslint-config-molindo": "^7.0.0",
25+
"eslint-config-next": "^14.0.3",
26+
"typescript": "^5.2.2"
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* eslint-disable import/no-extraneous-dependencies */
2+
import type {PlaywrightTestConfig} from '@playwright/test';
3+
import {devices} from '@playwright/test';
4+
5+
// Use a distinct port on CI to avoid conflicts during concurrent tests
6+
const PORT = process.env.CI ? 3001 : 3000;
7+
8+
const config: PlaywrightTestConfig = {
9+
retries: process.env.CI ? 1 : 0,
10+
testDir: './tests',
11+
projects: [
12+
{
13+
name: 'chromium',
14+
use: devices['Desktop Chrome']
15+
}
16+
],
17+
webServer: {
18+
command: `PORT=${PORT} pnpm start`,
19+
port: PORT,
20+
reuseExistingServer: true
21+
}
22+
};
23+
24+
export default config;
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import {useTranslations} from 'next-intl';
2+
import PageLayout from '@/components/PageLayout';
3+
4+
export default function About() {
5+
const t = useTranslations('About');
6+
7+
return (
8+
<PageLayout title={t('title')}>
9+
<p>{t('description')}</p>
10+
</PageLayout>
11+
);
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {NextIntlClientProvider, useLocale} from 'next-intl';
2+
import {ReactNode} from 'react';
3+
4+
type Props = {
5+
children: ReactNode;
6+
};
7+
8+
export default function LocaleLayout({children}: Props) {
9+
const locale = useLocale();
10+
11+
return (
12+
<html lang={locale}>
13+
<head>
14+
<title>next-intl</title>
15+
</head>
16+
<body>
17+
<NextIntlClientProvider>{children}</NextIntlClientProvider>
18+
</body>
19+
</html>
20+
);
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import Link from 'next/link';
2+
import {useTranslations} from 'next-intl';
3+
import PageLayout from '@/components/PageLayout';
4+
5+
export default function Index() {
6+
const t = useTranslations('Index');
7+
8+
return (
9+
<PageLayout title={t('title')}>
10+
<p>{t('description')}</p>
11+
<p>
12+
<Link href="/about">{t('navigateToAbout')}</Link>
13+
</p>
14+
</PageLayout>
15+
);
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import {ReactNode} from 'react';
2+
3+
type Props = {
4+
children?: ReactNode;
5+
title: string;
6+
};
7+
8+
export default function PageLayout({children, title}: Props) {
9+
return (
10+
<>
11+
<div
12+
style={{
13+
padding: 24,
14+
fontFamily: 'system-ui, sans-serif',
15+
lineHeight: 1.5
16+
}}
17+
>
18+
<div style={{maxWidth: 510}}>
19+
<h1>{title}</h1>
20+
{children}
21+
</div>
22+
</div>
23+
</>
24+
);
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import {getRequestConfig} from 'next-intl/server';
2+
3+
export default getRequestConfig(async () => {
4+
// This can either be defined statically if only a single locale
5+
// is supported, or alternatively read from the user settings.
6+
const locale = 'en';
7+
8+
return {
9+
locale,
10+
messages: (await import(`../messages/${locale}.json`)).default
11+
};
12+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import {test as it} from '@playwright/test';
2+
3+
it('uses the provided locale', async ({page}) => {
4+
await page.goto('/');
5+
page.getByRole('heading', {name: 'Home'});
6+
7+
await page.goto('/');
8+
page.getByRole('heading', {name: 'About'});
9+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"extends": "eslint-config-molindo/tsconfig.json",
3+
"compilerOptions": {
4+
"target": "es5",
5+
"lib": [
6+
"dom",
7+
"dom.iterable",
8+
"esnext"
9+
],
10+
"allowJs": true,
11+
"skipLibCheck": true,
12+
"noEmit": true,
13+
"esModuleInterop": true,
14+
"module": "esnext",
15+
"moduleResolution": "node",
16+
"resolveJsonModule": true,
17+
"isolatedModules": true,
18+
"jsx": "preserve",
19+
"incremental": true,
20+
"plugins": [
21+
{
22+
"name": "next"
23+
}
24+
],
25+
"paths": {
26+
"@/*": ["./src/*"]
27+
},
28+
"strictNullChecks": true
29+
},
30+
"include": [
31+
"next-env.d.ts",
32+
"**/*.ts",
33+
"**/*.tsx",
34+
".next/types/**/*.ts"
35+
],
36+
"exclude": [
37+
"node_modules"
38+
]
39+
}

0 commit comments

Comments
 (0)