[wip] implementing multi language
This commit is contained in:
5
messages/en.json
Normal file
5
messages/en.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"Home": {
|
||||||
|
"title": "Title"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +1,33 @@
|
|||||||
|
import { getDirection } from '@/i18n/direction'
|
||||||
|
import { routing } from '@/i18n/routing'
|
||||||
import { ClientAppProvider } from '@/providers/ClientAppProvider'
|
import { ClientAppProvider } from '@/providers/ClientAppProvider'
|
||||||
import '@/styles/globals.css'
|
import '@/styles/globals.css'
|
||||||
import type { Metadata } from 'next'
|
import type { Metadata } from 'next'
|
||||||
|
import { hasLocale, NextIntlClientProvider } from 'next-intl'
|
||||||
|
import { getMessages } from 'next-intl/server'
|
||||||
|
import { notFound } from 'next/navigation'
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: 'Theater of dreams',
|
title: 'Theater of dreams',
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function RootLayout({
|
export default async function RootLayout({
|
||||||
children,
|
children,
|
||||||
}: {
|
params,
|
||||||
|
}: Readonly<{
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
}) {
|
params: Promise<{ locale: string }>
|
||||||
|
}>) {
|
||||||
|
const { locale } = await params
|
||||||
|
if (!hasLocale(routing.locales, locale)) {
|
||||||
|
notFound()
|
||||||
|
}
|
||||||
|
|
||||||
|
const messages = await getMessages()
|
||||||
|
const dir = getDirection(locale)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang='en' suppressHydrationWarning>
|
<html dir={dir} lang={locale} suppressHydrationWarning>
|
||||||
<head>
|
<head>
|
||||||
{/* Prevent theme flicker before hydration */}
|
{/* Prevent theme flicker before hydration */}
|
||||||
<script
|
<script
|
||||||
@@ -31,7 +46,9 @@ export default function RootLayout({
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body className='bg-primary'>
|
<body className='bg-primary'>
|
||||||
<ClientAppProvider>{children}</ClientAppProvider>
|
<NextIntlClientProvider locale={locale} messages={messages}>
|
||||||
|
<ClientAppProvider>{children}</ClientAppProvider>
|
||||||
|
</NextIntlClientProvider>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
)
|
)
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
import ThemeToggle from '@/components/UI/ThemeToggle'
|
import ThemeToggle from '@/components/UI/ThemeToggle'
|
||||||
|
import { useTranslations } from 'next-intl'
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
|
const t = useTranslations('Home')
|
||||||
return (
|
return (
|
||||||
<main>
|
<main>
|
||||||
<ThemeToggle />
|
<ThemeToggle />
|
||||||
<h1>Offline Next.js Template 🚀</h1>
|
<h1>{t('title')}</h1>
|
||||||
<p>This project was generated completely offline.</p>
|
<p>This project was generated completely offline.</p>
|
||||||
</main>
|
</main>
|
||||||
)
|
)
|
||||||
10
src/i18n/direction.ts
Normal file
10
src/i18n/direction.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export type Direction = 'ltr' | 'rtl'
|
||||||
|
|
||||||
|
export const localeDirectionMap: Record<string, Direction> = {
|
||||||
|
en: 'ltr',
|
||||||
|
fa: 'rtl',
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDirection(locale: string): Direction {
|
||||||
|
return localeDirectionMap[locale] ?? 'ltr'
|
||||||
|
}
|
||||||
4
src/i18n/navigation.ts
Normal file
4
src/i18n/navigation.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import { createNavigation } from 'next-intl/navigation'
|
||||||
|
import { routing } from './routing'
|
||||||
|
|
||||||
|
export const { Link, redirect, usePathname, useRouter, getPathname } = createNavigation(routing)
|
||||||
15
src/i18n/request.ts
Normal file
15
src/i18n/request.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { getRequestConfig } from 'next-intl/server'
|
||||||
|
import { hasLocale } from 'next-intl'
|
||||||
|
import { routing } from './routing'
|
||||||
|
|
||||||
|
export default getRequestConfig(async ({ requestLocale }) => {
|
||||||
|
const requested = await requestLocale
|
||||||
|
const locale = hasLocale(routing.locales, requested)
|
||||||
|
? requested
|
||||||
|
: routing.defaultLocale
|
||||||
|
|
||||||
|
return {
|
||||||
|
locale,
|
||||||
|
messages: (await import(`../../messages/${locale}.json`)).default,
|
||||||
|
}
|
||||||
|
})
|
||||||
8
src/i18n/routing.ts
Normal file
8
src/i18n/routing.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineRouting } from 'next-intl/routing'
|
||||||
|
|
||||||
|
export const routing = defineRouting({
|
||||||
|
locales: ['en', 'fa'],
|
||||||
|
defaultLocale: 'en',
|
||||||
|
localePrefix: 'never',
|
||||||
|
localeDetection: false,
|
||||||
|
})
|
||||||
9
src/i18n/useDirection.ts
Normal file
9
src/i18n/useDirection.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useLocale } from 'next-intl'
|
||||||
|
import { Direction, getDirection } from './direction'
|
||||||
|
|
||||||
|
export function useDirection(): Direction {
|
||||||
|
const locale = useLocale()
|
||||||
|
return getDirection(locale)
|
||||||
|
}
|
||||||
6
src/lib/utils.ts
Normal file
6
src/lib/utils.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { clsx, type ClassValue } from 'clsx'
|
||||||
|
import { twMerge } from 'tailwind-merge'
|
||||||
|
|
||||||
|
export function cn(...inputs: ClassValue[]) {
|
||||||
|
return twMerge(clsx(inputs))
|
||||||
|
}
|
||||||
8
src/proxy.ts
Normal file
8
src/proxy.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import createMiddleware from 'next-intl/middleware'
|
||||||
|
import { routing } from './i18n/routing'
|
||||||
|
|
||||||
|
export default createMiddleware(routing)
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
matcher: '/((?!api|trpc|_next|_vercel|.*\\..*).*)',
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user