import type { ReactNode } from 'react'; import type { Metadata, Viewport } from 'next'; import localFont from 'next/font/local'; import { setRequestLocale, getMessages } from 'next-intl/server'; import { NextIntlClientProvider } from 'next-intl'; import { getThemeMode } from '@/lib/cookies/server'; import { AppStoreProvider } from '@/store'; import { ThemeProvider, getDirection } from '@/theme'; import { BRAND } from '@/theme/colors'; import { NotistackProvider } from '@/lib/toast'; import { QueryProvider } from '@/lib/query/QueryProvider'; import { routing } from '@/i18n/routing'; import '../globals.css'; import '@/theme/tokens.css'; /* * This is the application's ROOT layout — it renders and
. * * Why lives here and NOT in a layout above the [locale] segment: * `lang` and `dir` must track the active locale, and the only layout that * re-renders when the locale changes is the one keyed on the [locale] param. * A layout placed above [locale] is shared between /fa and /en, so it is * statically cached with the defaultLocale and never re-renders on a locale * switch — leaving `dir`/`lang` frozen on the default ('fa'/'rtl'). Sourcing * the locale from URL params here means no header reads, no caching surprises. * * setRequestLocale(locale) is called first so that any server component * deeper in the tree that calls getLocale() / getTranslations() gets the * right locale from React.cache instead of falling through to the header * fallback. getMessages({ locale }) passes the locale explicitly so the * config callback in src/i18n/request.ts receives it via requestLocale * directly (Promise.resolve(locale)) rather than reading it from the cache. */ // FA brand font — Mikhak, a free Persian typeface. // preload: false + conditional className (below) ensure the woff2 files are // only fetched on Persian routes, never on /en. const mikhak = localFont({ src: [ { path: '../fonts/Mikhak-Regular.woff2', weight: '400', style: 'normal' }, { path: '../fonts/Mikhak-Medium.woff2', weight: '500', style: 'normal' }, { path: '../fonts/Mikhak-Bold.woff2', weight: '700', style: 'normal' }, ], display: 'swap', variable: '--font-mikhak', preload: false, }); export const viewport: Viewport = { themeColor: BRAND.teal, }; export const metadata: Metadata = { title: 'Balinyaar | بالینیار', description: 'Balinyaar web application', manifest: '/site.webmanifest', }; export default async function LocaleLayout({ children, params, }: { children: ReactNode; params: Promise<{ locale: string }>; }) { const { locale } = await params; const safeLocale = routing.locales.includes(locale as (typeof routing.locales)[number]) ? locale : routing.defaultLocale; setRequestLocale(safeLocale); const messages = await getMessages({ locale: safeLocale }); const { colorScheme, defaultMode } = await getThemeMode(); const dir = getDirection(safeLocale); // Only attach the Mikhak font variable on RTL (Persian) routes so the // Persian typeface is not loaded for English pages. const fontClassName = safeLocale === 'fa' ? mikhak.variable : undefined; return (