[wip] implementing multi language

This commit is contained in:
2026-04-15 12:40:43 +03:30
parent e37f76ca5a
commit 415d794147
10 changed files with 90 additions and 6 deletions

5
messages/en.json Normal file
View File

@@ -0,0 +1,5 @@
{
"Home": {
"title": "Title"
}
}

View File

@@ -1,18 +1,33 @@
import { getDirection } from '@/i18n/direction'
import { routing } from '@/i18n/routing'
import { ClientAppProvider } from '@/providers/ClientAppProvider'
import '@/styles/globals.css'
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 = {
title: 'Theater of dreams',
}
export default function RootLayout({
export default async function RootLayout({
children,
}: {
params,
}: Readonly<{
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 (
<html lang='en' suppressHydrationWarning>
<html dir={dir} lang={locale} suppressHydrationWarning>
<head>
{/* Prevent theme flicker before hydration */}
<script
@@ -31,7 +46,9 @@ export default function RootLayout({
</head>
<body className='bg-primary'>
<ClientAppProvider>{children}</ClientAppProvider>
<NextIntlClientProvider locale={locale} messages={messages}>
<ClientAppProvider>{children}</ClientAppProvider>
</NextIntlClientProvider>
</body>
</html>
)

View File

@@ -1,10 +1,12 @@
import ThemeToggle from '@/components/UI/ThemeToggle'
import { useTranslations } from 'next-intl'
export default function Home() {
const t = useTranslations('Home')
return (
<main>
<ThemeToggle />
<h1>Offline Next.js Template 🚀</h1>
<h1>{t('title')}</h1>
<p>This project was generated completely offline.</p>
</main>
)

10
src/i18n/direction.ts Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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|.*\\..*).*)',
}