134 lines
3.4 KiB
TypeScript
134 lines
3.4 KiB
TypeScript
import type { Metadata } from 'next';
|
|
import './globals.css';
|
|
import ClientLayout from './ClientLayout';
|
|
import { getSeoConfig } from '../lib/seo';
|
|
|
|
export async function generateMetadata(): Promise<Metadata> {
|
|
const config = await getSeoConfig();
|
|
const siteUrl = config.canonicalBaseUrl || process.env.NEXT_PUBLIC_SITE_URL || 'https://canina.ir';
|
|
const titleDefault = config.defaultMetaTitle;
|
|
const descriptionDefault = config.defaultMetaDescription;
|
|
const keywordsList = config.keywords;
|
|
const ogImg = config.ogImageUrl;
|
|
const brandName = config.brandNameFa;
|
|
const separator = config.titleSeparator;
|
|
const position = config.titlePosition;
|
|
|
|
const templateStr =
|
|
position === 'prefix'
|
|
? `${brandName} ${separator} %s`
|
|
: position === 'none'
|
|
? '%s'
|
|
: `%s ${separator} ${brandName}`;
|
|
|
|
const isStaging =
|
|
process.env.NEXT_PUBLIC_APP_ENV === 'staging' ||
|
|
process.env.NODE_ENV !== 'production' ||
|
|
(typeof process.env.NEXT_PUBLIC_SITE_URL === 'string' && (
|
|
process.env.NEXT_PUBLIC_SITE_URL.includes('stage') ||
|
|
process.env.NEXT_PUBLIC_SITE_URL.includes('test') ||
|
|
process.env.NEXT_PUBLIC_SITE_URL.includes('dev')
|
|
));
|
|
|
|
return {
|
|
metadataBase: new URL(siteUrl),
|
|
title: {
|
|
template: templateStr,
|
|
default: titleDefault,
|
|
},
|
|
description: descriptionDefault,
|
|
keywords: keywordsList,
|
|
authors: [{ name: brandName }],
|
|
creator: brandName,
|
|
publisher: brandName,
|
|
robots: isStaging ? {
|
|
index: false,
|
|
follow: false,
|
|
nocache: true,
|
|
googleBot: {
|
|
index: false,
|
|
follow: false,
|
|
noimageindex: true,
|
|
}
|
|
} : {
|
|
index: true,
|
|
follow: true,
|
|
googleBot: {
|
|
index: true,
|
|
follow: true,
|
|
'max-video-preview': -1,
|
|
'max-image-preview': 'large',
|
|
'max-snippet': -1,
|
|
}
|
|
},
|
|
alternates: {
|
|
canonical: '/',
|
|
},
|
|
formatDetection: {
|
|
email: false,
|
|
address: false,
|
|
telephone: false,
|
|
},
|
|
openGraph: {
|
|
title: titleDefault,
|
|
description: descriptionDefault,
|
|
url: siteUrl,
|
|
siteName: brandName,
|
|
locale: 'fa_IR',
|
|
type: 'website',
|
|
images: [
|
|
{
|
|
url: ogImg,
|
|
width: 1200,
|
|
height: 630,
|
|
alt: titleDefault,
|
|
},
|
|
],
|
|
},
|
|
twitter: {
|
|
card: 'summary_large_image',
|
|
title: titleDefault,
|
|
description: descriptionDefault,
|
|
images: [ogImg],
|
|
},
|
|
};
|
|
}
|
|
|
|
export default function RootLayout({
|
|
children,
|
|
}: {
|
|
children: React.ReactNode;
|
|
}) {
|
|
const jsonLd = {
|
|
'@context': 'https://schema.org',
|
|
'@type': 'Organization',
|
|
name: 'کنینا ایران',
|
|
url: 'https://canina.ir',
|
|
logo: 'https://canina.de/media/fb/d5/47/1683116813/Logo.png',
|
|
contactPoint: {
|
|
'@type': 'ContactPoint',
|
|
telephone: '+98-21-88884444',
|
|
contactType: 'customer service',
|
|
email: 'info@canina.ir',
|
|
areaServed: 'IR',
|
|
availableLanguage: 'Persian'
|
|
}
|
|
};
|
|
|
|
const safeJsonLd = JSON.stringify(jsonLd).replace(/</g, '\\u003c');
|
|
|
|
return (
|
|
<html lang="fa" dir="rtl" suppressHydrationWarning>
|
|
<body className="min-h-screen bg-medical-gray-50 font-sans" suppressHydrationWarning>
|
|
<script
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{ __html: safeJsonLd }}
|
|
/>
|
|
<ClientLayout>
|
|
{children}
|
|
</ClientLayout>
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|