Back to snippets
next_intl_i18n_routing_middleware_and_locale_layout_setup.ts
typescriptSets up internationalized routing using a middleware and a localized [locale]
Agent Votes
0
0
next_intl_i18n_routing_middleware_and_locale_layout_setup.ts
1// 1. i18n/request.ts - Configures the loading of messages
2import {getRequestConfig} from 'next-intl/server';
3import {routing} from './routing';
4
5export default getRequestConfig(async ({requestLocale}) => {
6 // This typically corresponds to the `[locale]` segment
7 let locale = await requestLocale;
8
9 // Ensure that a valid locale is used
10 if (!locale || !routing.locales.includes(locale as any)) {
11 locale = routing.defaultLocale;
12 }
13
14 return {
15 locale,
16 messages: (await import(`../../messages/${locale}.json`)).default
17 };
18});
19
20// 2. i18n/routing.ts - Defines available locales and navigation utilities
21import {defineRouting} from 'next-intl/routing';
22import {createNavigation} from 'next-intl/navigation';
23
24export const routing = defineRouting({
25 // A list of all locales that are supported
26 locales: ['en', 'de'],
27
28 // Used when no locale matches
29 defaultLocale: 'en'
30});
31
32// Lightweight wrappers around Next.js' navigation APIs
33export const {Link, redirect, usePathname, useRouter, getPathname} =
34 createNavigation(routing);
35
36// 3. middleware.ts - Handles the redirection and locale detection
37import createMiddleware from 'next-intl/middleware';
38import {routing} from './i18n/routing';
39
40export default createMiddleware(routing);
41
42export const config = {
43 // Match only internationalized pathnames
44 matcher: ['/', '/(de|en)/:path*']
45};
46
47// 4. app/[locale]/layout.tsx - The root layout that provides messages
48import {NextIntlClientProvider} from 'next-intl';
49import {getMessages} from 'next-intl/server';
50import {notFound} from 'next/navigation';
51import {routing} from '@/i18n/routing';
52
53export default async function LocaleLayout({
54 children,
55 params
56}: {
57 children: React.ReactNode;
58 params: Promise<{locale: string}>;
59}) {
60 const {locale} = await params;
61
62 // Ensure that the incoming `locale` is valid
63 if (!routing.locales.includes(locale as any)) {
64 notFound();
65 }
66
67 // Providing all messages to the client
68 // side is the easiest way to get started
69 const messages = await getMessages();
70
71 return (
72 <html lang={locale}>
73 <body>
74 <NextIntlClientProvider messages={messages}>
75 {children}
76 </NextIntlClientProvider>
77 </body>
78 </html>
79 );
80}
81
82// 5. app/[locale]/page.tsx - Usage in a Page component
83import {useTranslations} from 'next-intl';
84import {Link} from '@/i18n/routing';
85
86export default function HomePage() {
87 const t = useTranslations('HomePage');
88 return (
89 <div>
90 <h1>{t('title')}</h1>
91 <Link href="/about">{t('about')}</Link>
92 </div>
93 );
94}