Add Torob tags, Meshkee SEO routes, and updated static-image slots.

Product pages emit crawler-readable meta, public URLs use id plus Farsi slugs, and the homepage catalog matches the dashboard slot keys.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-09-01 16:12:26 +03:30
co-authored by Cursor
parent f42c30a4b7
commit c84147e765
40 changed files with 838 additions and 288 deletions
+72
View File
@@ -0,0 +1,72 @@
import type { Metadata } from "next";
import { notFound, permanentRedirect } from "next/navigation";
import { PageHero } from "@/components/PageHero";
import { ProductTabs } from "@/components/ProductTabs";
import { ProductView } from "@/components/ProductView";
import { getComments, getProductById, getStoreItemByProduct } from "@/lib/api";
import { productHref, productNameSlug, productTitle } from "@/lib/paths";
import { SITE } from "@/lib/site";
import { torobMetadata } from "@/lib/torob";
type Props = {
params: Promise<{ id: string; slug: string }>;
};
async function loadProduct(id: string) {
return getProductById(id);
}
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { id } = await params;
try {
const product = await loadProduct(id);
if (!product) return { title: SITE.nameFa };
let storeItem = null;
try {
storeItem = await getStoreItemByProduct(product.id);
} catch {
storeItem = null;
}
const title = productTitle(product);
return {
title: `${title} | ${SITE.nameFa}`,
description: product.summary?.trim() || SITE.tagline,
alternates: { canonical: productHref(product) },
...torobMetadata(product, storeItem),
};
} catch {
return { title: SITE.nameFa };
}
}
export default async function ProductDetailsPage({ params }: Props) {
const { id, slug } = await params;
const product = await loadProduct(id);
if (!product) notFound();
const title = productTitle(product);
if (decodeURIComponent(slug) !== productNameSlug(title)) {
permanentRedirect(productHref(product));
}
const [storeItem, comments] = await Promise.all([
getStoreItemByProduct(product.id),
getComments("product", product.id),
]);
return (
<>
<PageHero
title={title}
english={product.title}
crumbs={[{ name: "محصولات", href: "/products" }, { name: title }]}
/>
<section className="container-site py-10 md:py-14">
<ProductView product={product} variants={storeItem?.variants ?? []} />
<ProductTabs productId={product.id} descriptionHtml={product.descriptionHtml} comments={comments} />
</section>
</>
);
}