diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx new file mode 100644 index 0000000..9f3570f --- /dev/null +++ b/src/app/[locale]/layout.tsx @@ -0,0 +1,83 @@ +import { NextIntlClientProvider } from 'next-intl'; +import { getMessages, getTranslations } from 'next-intl/server'; +import { Inter, Vazirmatn } from 'next/font/google'; +import { routing } from '@/i18n/routing'; +import { notFound } from 'next/navigation'; +import '@/app/globals.css'; + +const inter = Inter({ + subsets: ['latin'], + variable: '--font-sans', +}); + +const vazirmatn = Vazirmatn({ + subsets: ['arabic'], + variable: '--font-farsi', +}); + +type Props = { + children: React.ReactNode; + params: Promise<{ locale?: string }>; +}; + +export async function generateMetadata({ params }: { params: Promise<{ locale?: string }> }) { + const { locale = 'en' } = await params; + const t = await getTranslations({ locale, namespace: 'Metadata' }); + return { + title: t('title'), + description: t('description'), + alternates: { + canonical: locale === 'en' ? 'https://arsamsabbagh.ir/' : 'https://arsamsabbagh.ir/fa', + languages: { + en: 'https://arsamsabbagh.ir/', + fa: 'https://arsamsabbagh.ir/fa', + }, + }, + }; +} + +export default async function LocaleLayout({ children, params }: Props) { + const { locale = 'en' } = await params; + + + // Validate that the incoming `locale` parameter is valid + if (!routing.locales.includes(locale as any)) { + notFound(); + } + + // Get messages for the locale + const messages = await getMessages(); + + const direction = locale === 'fa' ? 'rtl' : 'ltr'; + + // Inline script to prevent theme flash + const themeScript = ` + (function() { + try { + var theme = localStorage.getItem('theme'); + if (theme === 'dark' || (!theme && window.matchMedia('(prefers-color-scheme: dark)').matches)) { + document.documentElement.classList.add('dark'); + } else { + document.documentElement.classList.remove('dark'); + } + } catch (e) {} + })(); + `; + + return ( + +
+ + + +