Back to snippets

next_intl_i18n_routing_middleware_and_locale_layout_setup.ts

typescript

Sets 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}