Files
BarevClub/apps/landing/app/[locale]/layout.tsx
T
2026-10-25 22:55:29 +04:00

57 lines
2.7 KiB
TypeScript

import '@barev/ui/styles.css';
import '../landing.css';
import { createT, isLocale, LOCALES, type Locale } from '@barev/i18n';
import type { Metadata, Viewport } from 'next';
import { Noto_Sans_Armenian, Onest, Rubik } from 'next/font/google';
import { notFound } from 'next/navigation';
import type { ReactNode } from 'react';
const rubik = Rubik({ subsets: ['latin', 'cyrillic'], weight: ['400', '500', '700', '800'], style: ['normal', 'italic'], variable: '--font-rubik', display: 'swap' });
const onest = Onest({ subsets: ['latin', 'cyrillic'], weight: ['400', '500', '600'], variable: '--font-onest', display: 'swap' });
const armenian = Noto_Sans_Armenian({ subsets: ['armenian'], weight: ['400', '600', '700'], variable: '--font-armenian', display: 'swap', preload: false });
const SITE = process.env.LANDING_URL ?? 'http://localhost:3000';
export function generateStaticParams() {
return LOCALES.map((locale) => ({ locale }));
}
export const viewport: Viewport = { themeColor: '#FBF6EE', width: 'device-width', initialScale: 1 };
/** LND-4: SEO-мета на каждом языке и hreflang */
export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }): Promise<Metadata> {
const { locale } = await params;
if (!isLocale(locale)) return {};
const t = createT(locale);
// по умолчанию — заголовок и описание главной (страницы задают свои)
const title = t('landing.home.metaTitle');
const description = t('landing.home.metaDescription');
return {
metadataBase: new URL(SITE),
title,
description,
alternates: {
canonical: `/${locale}`,
languages: Object.fromEntries([...LOCALES.map((l) => [l, `/${l}`]), ['x-default', '/ru']]),
},
openGraph: { title, description, locale, type: 'website', siteName: 'Barev Club' },
twitter: { card: 'summary_large_image' },
// подтверждение прав в Search Console, Яндекс Вебмастере и Bing — коды из .env (можно и через DNS)
verification: {
google: process.env.GOOGLE_SITE_VERIFICATION || undefined,
yandex: process.env.YANDEX_VERIFICATION || undefined,
other: process.env.BING_SITE_VERIFICATION ? { 'msvalidate.01': process.env.BING_SITE_VERIFICATION } : undefined,
},
};
}
export default async function LocaleLayout({ children, params }: { children: ReactNode; params: Promise<{ locale: string }> }) {
const { locale } = await params;
if (!isLocale(locale)) notFound();
return (
<html lang={locale as Locale} className={`${rubik.variable} ${onest.variable} ${armenian.variable}`}>
<body>{children}</body>
</html>
);
}