Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions examples/example-app-router-patterns/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/node_modules
/.next/
.DS_Store
tsconfig.tsbuildinfo
9 changes: 9 additions & 0 deletions examples/example-app-router-patterns/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# example-app-router-patterns

This example demonstrates various use cases and patterns for using `next-intl` with the App Router.

## Deploy your own

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.

[![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-patterns)
22 changes: 22 additions & 0 deletions examples/example-app-router-patterns/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {dirname} from 'path';
import {fileURLToPath} from 'url';
import {FlatCompat} from '@eslint/eslintrc';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

const compat = new FlatCompat({
baseDirectory: __dirname
});

const eslintConfig = [
...compat.extends('next/core-web-vitals', 'next/typescript'),
{
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/ban-ts-comment': 'off'
}
}
];

export default eslintConfig;
6 changes: 6 additions & 0 deletions examples/example-app-router-patterns/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference path="./.next/types/routes.d.ts" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
4 changes: 4 additions & 0 deletions examples/example-app-router-patterns/next.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/** @type {import('next').NextConfig} */
const nextConfig = {};

export default nextConfig;
44 changes: 44 additions & 0 deletions examples/example-app-router-patterns/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "example-app-router-patterns",
"private": true,
"scripts": {
"dev": "next dev",
"lint": "eslint src && prettier src --check",
"build": "next build",
"start": "next start"
},
"dependencies": {
"clsx": "^2.1.1",
"next": "^15.5.0",
"next-intl": "^4.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"tailwindcss": "^4.1.12"
},
"devDependencies": {
"@eslint/eslintrc": "^3.1.0",
"@tailwindcss/postcss": "^4.1.12",
"@types/node": "^20.14.5",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"eslint": "9.11.1",
"eslint-config-next": "^15.5.0",
"postcss": "^8.5.3",
"prettier": "^3.3.3",
"prettier-plugin-organize-imports": "^4.2.0",
"prettier-plugin-tailwindcss": "^0.6.14",
"typescript": "^5.5.3"
},
"prettier": {
"singleQuote": true,
"bracketSpacing": false,
"trailingComma": "none",
"plugins": [
"prettier-plugin-organize-imports",
"prettier-plugin-tailwindcss"
]
},
"engines": {
"node": ">=20.0.0"
}
}
6 changes: 6 additions & 0 deletions examples/example-app-router-patterns/postcss.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const config = {
plugins: {
'@tailwindcss/postcss': {}
}
};
export default config;
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import clsx from 'clsx';

type Props = {
className: string;
value: string;
};

export default function DesignColorSwatch({className, value}: Props) {
return (
<div className="flex flex-col items-center gap-2">
<div className={clsx(className, 'size-20')} />
<div className="text-sm">{value}</div>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {ReactNode} from 'react';

type Props = {
children: ReactNode;
title: string;
};

export default function DesignSection({children, title}: Props) {
return (
<section className="space-y-8">
<h2 className="text-5xl font-semibold tracking-tight text-gray-900">
{title}
</h2>
{children}
</section>
);
}
170 changes: 170 additions & 0 deletions examples/example-app-router-patterns/src/app/design/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
// Documentation page for the next-intl design system

import DesignColorSwatch from './DesignColorSwatch';
import DesignSection from './DesignSection';

export default function DesignPage() {
return (
<div>
<div className="mx-auto max-w-6xl p-20">
<p className="text-6xl font-semibold tracking-tight text-gray-900">
Design system
</p>
<div className="mt-20 space-y-16">
<DesignSection title="Colors">
<div className="space-y-8">
<div className="space-y-2">
<p className="text-xl font-semibold text-gray-900">
Blue (primary)
</p>
<div className="flex items-center space-x-1">
<DesignColorSwatch className="bg-gray-100" value="50" />
<DesignColorSwatch className="bg-gray-100" value="100" />
<DesignColorSwatch className="bg-gray-100" value="200" />
<DesignColorSwatch className="bg-blue-300" value="300" />
<DesignColorSwatch className="bg-gray-100" value="400" />
<DesignColorSwatch className="bg-gray-100" value="500" />
<DesignColorSwatch className="bg-gray-100" value="600" />
<DesignColorSwatch className="bg-blue-700" value="700" />
<DesignColorSwatch className="bg-gray-100" value="800" />
<DesignColorSwatch className="bg-gray-100" value="900" />
</div>
</div>
<div className="space-y-2">
<p className="text-xl font-semibold text-gray-900">Gray</p>
<div className="flex items-center space-x-1">
<DesignColorSwatch className="bg-gray-50" value="50" />
<DesignColorSwatch className="bg-gray-100" value="100" />
<DesignColorSwatch className="bg-gray-200" value="200" />
<DesignColorSwatch className="bg-gray-300" value="300" />
<DesignColorSwatch className="bg-gray-400" value="400" />
<DesignColorSwatch className="bg-gray-500" value="500" />
<DesignColorSwatch className="bg-gray-600" value="600" />
<DesignColorSwatch className="bg-gray-700" value="700" />
<DesignColorSwatch className="bg-gray-800" value="800" />
<DesignColorSwatch className="bg-gray-900" value="900" />
</div>
</div>
</div>
</DesignSection>
<DesignSection title="Typography">
<div className="grid grid-cols-2">
<div className="bg-white py-8">
<div className="space-y-6">
<p className="text-6xl font-semibold tracking-tight text-gray-900">
Title large
</p>
<p className="text-5xl font-semibold tracking-tight text-gray-900">
Title normal
</p>
<p className="text-xl text-gray-600">Title description</p>
<p className="text-sm font-semibold tracking-wide text-blue-700 uppercase">
Title caption
</p>
<p className="text-3xl font-semibold text-gray-900">
Title small
</p>
<p className="text-xl font-semibold text-gray-900">
Headline
</p>
<p className="text-xs font-semibold tracking-wide text-blue-700 uppercase">
Headline caption
</p>
<p className="text-lg text-gray-700">Body large</p>
<p className="text-lg text-gray-500">Body large muted</p>
<p className="text-base text-gray-700">
Body with{' '}
<a
href="#"
className="font-semibold text-gray-900 underline decoration-blue-700 underline-offset-2"
>
a link
</a>
</p>
<p className="text-base text-gray-500">Body muted</p>
<p className="text-sm font-semibold text-gray-900">Label</p>
<p className="text-sm font-semibold text-gray-500">
Label muted
</p>
<p className="inline-block rounded border border-gray-100 bg-gray-50 px-1 py-0.5 font-mono text-base text-[0.9em] whitespace-pre">
Inline code
</p>
</div>
</div>
<div className="bg-gray-900 p-8">
<div className="space-y-6">
<p className="text-6xl font-semibold tracking-tight text-white">
Title large
</p>
<p className="text-5xl font-semibold tracking-tight text-white">
Title normal
</p>
<p className="text-xl text-gray-200">Title description</p>
<p className="text-sm font-semibold tracking-wide text-blue-300 uppercase">
Title caption
</p>
<p className="text-3xl font-semibold text-white">
Title small
</p>
<p className="text-xl font-semibold text-white">Headline</p>
<p className="text-xs font-semibold tracking-wide text-blue-300 uppercase">
Headline caption
</p>
<p className="text-lg text-white">Body large</p>
<p className="text-lg text-gray-300">Body large muted</p>
<p className="text-base text-gray-100">
Body with{' '}
<a
href="#"
className="font-semibold text-white underline decoration-blue-300 underline-offset-2"
>
a link
</a>
</p>
<p className="text-base text-gray-300">Body muted</p>
<p className="text-sm font-semibold text-white">Label</p>
<p className="text-sm font-semibold text-gray-200">
Label muted
</p>
<p className="inline-block rounded border border-gray-700 bg-gray-800 px-1 py-0.5 font-mono text-base text-[0.9em] whitespace-pre text-white">
Inline code
</p>
</div>
</div>
</div>
</DesignSection>
<DesignSection title="Surfaces">
<div className="grid grid-cols-2">
<div className="bg-white py-8 pr-8">
<div className="rounded-lg border border-gray-100 bg-gray-50 p-8">
<p className="text-sm font-semibold tracking-wide text-blue-700 uppercase">
Title caption
</p>
<p className="mt-2 text-5xl font-semibold tracking-tight text-gray-900">
Title normal
</p>
<p className="mt-4 text-xl text-gray-600">
Title description
</p>
</div>
</div>
<div className="bg-gray-900 p-8">
<div className="rounded-lg border border-gray-700 bg-gray-800 p-8">
<p className="text-sm font-semibold tracking-wide text-blue-300 uppercase">
Title caption
</p>
<p className="mt-2 text-5xl font-semibold tracking-tight text-white">
Title normal
</p>
<p className="mt-4 text-xl text-gray-200">
Title description
</p>
</div>
</div>
</div>
</DesignSection>
</div>
</div>
</div>
);
}
Binary file not shown.
23 changes: 23 additions & 0 deletions examples/example-app-router-patterns/src/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@import 'tailwindcss';

@theme {
--color-white: #ffffff;

--color-gray-50: #f7f7f8;
--color-gray-100: #ebebef;
--color-gray-200: #d1d1db;
--color-gray-300: #a9a9bc;
--color-gray-400: #8a8aa3;
--color-gray-500: #6c6c89;
--color-gray-600: #55556d;
--color-gray-700: #3f3f50;
--color-gray-800: #282833;
--color-gray-900: #121217;

--color-blue-300: #70d2ff;
--color-blue-700: #008fd6;

--font-mono:
Monaco, ui-monospace, SFMono-Regular, Menlo, Consolas, Liberation Mono,
Courier New, monospace;
}
16 changes: 16 additions & 0 deletions examples/example-app-router-patterns/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {Inter} from 'next/font/google';
import './globals.css';
import {clsx} from 'clsx';

const inter = Inter({
subsets: ['latin'],
variable: '--font-inter'
});

export default function RootLayout({children}: LayoutProps<'/'>) {
return (
<html>
<body className={clsx(inter.variable, 'antialiased')}>{children}</body>
</html>
);
}
5 changes: 5 additions & 0 deletions examples/example-app-router-patterns/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import {redirect} from 'next/navigation';

export default function HomePage() {
redirect('/design');
}
30 changes: 30 additions & 0 deletions examples/example-app-router-patterns/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"compilerOptions": {
"allowArbitraryExtensions": true,
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"strict": true,
"allowJs": true,
"skipLibCheck": true,
"noEmit": true,
"esModuleInterop": true,
"module": "ESNext",
"moduleResolution": "Bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"]
},
// See https://github.com/amannn/next-intl/pull/1509
"declaration": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
Loading