summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiqdad <ahmadmiqdad27@gmail.com>2025-09-29 12:18:09 +0700
committerMiqdad <ahmadmiqdad27@gmail.com>2025-09-29 12:18:09 +0700
commit6174fcca46f50be04a48f02098cb049e94e455d3 (patch)
tree1599a22e609b194e00d2f6eeed72c244e65a6c66
parent33ee63af39d27062a9d5f296640c88cf5ff74334 (diff)
<miqdad>crawl-fix
-rw-r--r--src-migrate/modules/product-detail/components/Breadcrumb.tsx3
-rw-r--r--src-migrate/pages/shop/product/[slug].tsx62
2 files changed, 31 insertions, 34 deletions
diff --git a/src-migrate/modules/product-detail/components/Breadcrumb.tsx b/src-migrate/modules/product-detail/components/Breadcrumb.tsx
index 0e263fe9..a0f983d0 100644
--- a/src-migrate/modules/product-detail/components/Breadcrumb.tsx
+++ b/src-migrate/modules/product-detail/components/Breadcrumb.tsx
@@ -10,12 +10,13 @@ type Props = { id: number; name: string };
const Breadcrumb = ({ id, name }: Props) => {
const { isDesktop, isMobile } = useDevice();
- const { data: breadcrumbs = [] } = useQuery({
+ const { data } = useQuery({
queryKey: ['product-category-breadcrumb', id],
queryFn: () => getProductCategoryBreadcrumb(id),
refetchOnWindowFocus: false,
});
+ const breadcrumbs = data ?? [];
const total = breadcrumbs.length;
const lastCat = total ? breadcrumbs[total - 1] : null;
const hasHidden = total > 1;
diff --git a/src-migrate/pages/shop/product/[slug].tsx b/src-migrate/pages/shop/product/[slug].tsx
index fc72a6b0..90658544 100644
--- a/src-migrate/pages/shop/product/[slug].tsx
+++ b/src-migrate/pages/shop/product/[slug].tsx
@@ -18,34 +18,41 @@ type PageProps = {
product: IProductDetail
}
-export const getServerSideProps: GetServerSideProps<PageProps> = (async (context) => {
- const { slug } = context.query
+export const getServerSideProps: GetServerSideProps<PageProps & { canonicalPath: string }> = async (context) => {
+ const { slug } = context.query;
const cookieString = context.req.headers.cookie;
const cookies = cookieString ? cookie.parse(cookieString) : {};
const auth = cookies?.auth ? JSON.parse(cookies.auth) : {};
- const tier = auth?.pricelist || ''
+ const tier = auth?.pricelist || '';
- const productId = getIdFromSlug(slug as string)
+ const productId = getIdFromSlug(slug as string);
+ const product = await getProductById(productId, tier);
- const product = await getProductById(productId, tier)
+ // ❌ produk tidak ada → 404
+ if (!product) return { notFound: true };
- if (!product) return { notFound: true }
+ // ❌ tidak ada variants atau tidak ada yang harga > 0 → 404
+ const hasValidVariant = Array.isArray(product.variants)
+ && product.variants.some(v => (v?.price?.price ?? 0) > 0);
+ if (!hasValidVariant) return { notFound: true };
+
+ // Canonical path aman untuk SSR (hindari router.asPath di server)
+ const canonicalPath = context.resolvedUrl || `/product/${slug}`;
+
+ return { props: { product, canonicalPath } };
+};
- return {
- props: { product }
- }
-})
const SELF_HOST = process.env.NEXT_PUBLIC_SELF_HOST
-const ProductDetailPage: NextPage<PageProps> = ({ product }) => {
+const ProductDetailPage: NextPage<PageProps & { canonicalPath: string }> = ({ product, canonicalPath }) => {
const router = useRouter();
-
const { setProduct } = useProductContext();
- useEffect(() => {
- if (product) setProduct(product);
- }, [product, setProduct]);
+ useEffect(() => { if (product) setProduct(product); }, [product, setProduct]);
+
+ const origin = process.env.NEXT_PUBLIC_SELF_HOST || '';
+ const url = origin + (canonicalPath?.startsWith('/') ? canonicalPath : `/${canonicalPath}`);
return (
<BasicLayout>
@@ -53,31 +60,20 @@ const ProductDetailPage: NextPage<PageProps> = ({ product }) => {
title={`${product.name} - Indoteknik.com`}
description='Temukan pilihan produk B2B Industri &amp; Alat Teknik untuk Perusahaan, UMKM &amp; Pemerintah dengan lengkap, mudah dan transparan.'
openGraph={{
- url: SELF_HOST + router.asPath,
- images: [
- {
- url: product?.image,
- width: 800,
- height: 800,
- alt: product?.name,
- },
- ],
+ url,
+ images: [{ url: product?.image, width: 800, height: 800, alt: product?.name }],
type: 'product',
}}
- additionalMetaTags={[
- {
- name: 'keywords',
- content: `${product?.name}, Harga ${product?.name}, Beli ${product?.name}, Spesifikasi ${product?.name}`,
- }
- ]}
- canonical={SELF_HOST + router.asPath}
+ additionalMetaTags={[{ name: 'keywords', content: `${product?.name}, Harga ${product?.name}, Beli ${product?.name}, Spesifikasi ${product?.name}` }]}
+ canonical={url}
/>
<div className='md:container pt-4 md:pt-6'>
<ProductDetail product={product} />
</div>
</BasicLayout>
- )
-}
+ );
+};
+
export default ProductDetailPage \ No newline at end of file