110 lines
3.3 KiB
TypeScript
110 lines
3.3 KiB
TypeScript
import type { Metadata } from 'next';
|
|
import '../globals.css';
|
|
import { locales, Locale, defaultLocale } from '../../lib/i18n';
|
|
import { getTranslations } from '../../lib/translations';
|
|
import {
|
|
generateAlternateLinks,
|
|
generateCanonicalUrl,
|
|
generateStructuredData,
|
|
} from '../../lib/seo-utils';
|
|
import { notFound } from 'next/navigation';
|
|
|
|
export async function generateStaticParams() {
|
|
return locales.map((locale) => ({ locale }));
|
|
}
|
|
|
|
export async function generateMetadata({
|
|
params,
|
|
}: {
|
|
params: { locale: Locale };
|
|
}): Promise<Metadata> {
|
|
const translations = getTranslations(params.locale);
|
|
const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || 'https://your-domain.com';
|
|
|
|
const alternateLinks = generateAlternateLinks('', baseUrl);
|
|
const canonicalUrl = generateCanonicalUrl('', params.locale, baseUrl);
|
|
|
|
return {
|
|
title: {
|
|
default: translations.meta.title,
|
|
template: `%s | ${translations.meta.title}`,
|
|
},
|
|
description: translations.meta.description,
|
|
keywords: translations.meta.keywords,
|
|
|
|
authors: [{ name: translations.meta.author }],
|
|
creator: translations.meta.author,
|
|
publisher: translations.meta.author,
|
|
formatDetection: {
|
|
email: false,
|
|
address: false,
|
|
telephone: false,
|
|
},
|
|
metadataBase: new URL(baseUrl),
|
|
alternates: {
|
|
canonical: canonicalUrl,
|
|
languages: Object.fromEntries(alternateLinks.map((link) => [link.hrefLang, link.href])),
|
|
},
|
|
openGraph: {
|
|
title: translations.meta.title,
|
|
description: translations.meta.description,
|
|
url: canonicalUrl,
|
|
siteName: translations.meta.title,
|
|
locale: params.locale,
|
|
alternateLocale: locales.filter((loc) => loc !== params.locale),
|
|
type: 'website',
|
|
images: [
|
|
{
|
|
url: `${baseUrl}/og-image.jpg`,
|
|
width: 1200,
|
|
height: 630,
|
|
alt: translations.meta.title,
|
|
},
|
|
],
|
|
},
|
|
twitter: {
|
|
card: 'summary_large_image',
|
|
title: translations.meta.title,
|
|
description: translations.meta.description,
|
|
images: [`${baseUrl}/og-image.jpg`],
|
|
creator: '@yourtwitterhandle',
|
|
},
|
|
robots: {
|
|
index: true,
|
|
follow: true,
|
|
googleBot: {
|
|
index: true,
|
|
follow: true,
|
|
'max-video-preview': -1,
|
|
'max-image-preview': 'large',
|
|
'max-snippet': -1,
|
|
},
|
|
},
|
|
verification: {
|
|
google: 'your-google-verification-code',
|
|
// Add other search engine verification codes as needed
|
|
},
|
|
};
|
|
}
|
|
|
|
export default function RootLayout({
|
|
children,
|
|
params,
|
|
}: {
|
|
children: React.ReactNode;
|
|
params: { locale: Locale };
|
|
}) {
|
|
// Validate that the incoming `locale` parameter is valid
|
|
if (!locales.includes(params.locale)) {
|
|
notFound();
|
|
}
|
|
|
|
return (
|
|
<html lang={params.locale} data-oid="9-vbv6i">
|
|
<body className="" data-oid="2snbkeg">
|
|
{children}
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|