123 lines
3.5 KiB
TypeScript
123 lines
3.5 KiB
TypeScript
import ProductPage from "../../../components/ProductPage";
|
|
import { productService } from "../../../lib/services/productService";
|
|
import type { Metadata, ResolvingMetadata } from 'next';
|
|
|
|
export async function generateMetadata(
|
|
{ params }: { params: Promise<{ slug: string }> },
|
|
parent: ResolvingMetadata
|
|
): Promise<Metadata> {
|
|
const resolvedParams = await params;
|
|
const product = await productService.getProductBySlug(resolvedParams.slug);
|
|
|
|
if (!product) {
|
|
return {
|
|
title: 'محصول یافت نشد',
|
|
};
|
|
}
|
|
|
|
// Get raw data for custom fields if we added them (like metaTitle)
|
|
// Since we don't have local access to raw DB object without modifying productService,
|
|
// we can just use the mapped product fields for now.
|
|
const nameFa = product.nameFa || product.name;
|
|
const nameEn = product.nameEn || "";
|
|
const title = nameFa.includes("Canina") ? nameFa : `${nameFa} (${nameEn}) | برند کانینا آلمان`;
|
|
const description = (product.shortDescription || product.description || '').substring(0, 150).trim();
|
|
const keywords = (product as any).keywords ? (product as any).keywords.split(',') : product.main_ingredients;
|
|
|
|
return {
|
|
title,
|
|
description,
|
|
keywords,
|
|
openGraph: {
|
|
title,
|
|
description,
|
|
images: [product.image],
|
|
url: `/shop/${resolvedParams.slug}`,
|
|
siteName: "کانینا ایران",
|
|
type: "website",
|
|
},
|
|
alternates: {
|
|
canonical: `/shop/${resolvedParams.slug}`,
|
|
}
|
|
};
|
|
}
|
|
|
|
export default async function ShopProductPage({ params }: { params: Promise<{ slug: string }> }) {
|
|
const resolvedParams = await params;
|
|
const product = await productService.getProductBySlug(resolvedParams.slug);
|
|
|
|
if (!product) {
|
|
return <ProductPage productSlug={resolvedParams.slug} />;
|
|
}
|
|
|
|
const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://canina-iran.com';
|
|
const productUrl = `${siteUrl}/shop/${resolvedParams.slug}`;
|
|
const priceInRial = product.priceValue * 10;
|
|
|
|
const productJsonLd = {
|
|
'@context': 'https://schema.org',
|
|
'@type': 'Product',
|
|
name: product.nameFa || product.name,
|
|
image: product.image,
|
|
description: product.shortDescription || product.description,
|
|
sku: product.artNo,
|
|
mpn: product.artNo,
|
|
brand: {
|
|
'@type': 'Brand',
|
|
name: 'Canina pharma GmbH'
|
|
},
|
|
category: product.category,
|
|
offers: {
|
|
'@type': 'Offer',
|
|
url: productUrl,
|
|
priceCurrency: 'IRR',
|
|
price: priceInRial,
|
|
availability: 'https://schema.org/InStock',
|
|
itemCondition: 'https://schema.org/NewCondition',
|
|
seller: {
|
|
'@type': 'Organization',
|
|
name: 'کانینا ایران'
|
|
}
|
|
}
|
|
};
|
|
|
|
const breadcrumbJsonLd = {
|
|
'@context': 'https://schema.org',
|
|
'@type': 'BreadcrumbList',
|
|
itemListElement: [
|
|
{
|
|
'@type': 'ListItem',
|
|
position: 1,
|
|
name: 'صفحه اصلی',
|
|
item: siteUrl
|
|
},
|
|
{
|
|
'@type': 'ListItem',
|
|
position: 2,
|
|
name: 'فروشگاه مکملها',
|
|
item: `${siteUrl}/shop`
|
|
},
|
|
{
|
|
'@type': 'ListItem',
|
|
position: 3,
|
|
name: product.nameFa || product.name,
|
|
item: productUrl
|
|
}
|
|
]
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<script
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(productJsonLd) }}
|
|
/>
|
|
<script
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbJsonLd) }}
|
|
/>
|
|
<ProductPage productSlug={resolvedParams.slug} />
|
|
</>
|
|
);
|
|
}
|