import type { Metadata } from 'next'; import { notFound } from 'next/navigation'; import { BackButton } from '@/components/product/BackButton'; import { ProductDescription } from '@/components/product/ProductDescription'; import { container } from '@/lib/utils'; import { ProductProvider } from 'components/product/product-context'; import { ProductDetailsSection } from 'components/product/ProductDetailsSection'; import { ProductGallery } from 'components/product/ProductGallery'; import { HIDDEN_PRODUCT_TAG } from 'lib/constants'; import { getProduct } from 'lib/shopify'; import { Suspense } from 'react'; export async function generateMetadata(props: { params: Promise<{ handle: string }>; }): Promise { const params = await props.params; const product = await getProduct(params.handle); if (!product) return notFound(); const { url, width, height, altText: alt } = product.featuredImage || {}; const indexable = !product.tags.includes(HIDDEN_PRODUCT_TAG); return { title: product.seo.title || product.title, description: product.seo.description || product.description, robots: { index: indexable, follow: indexable, googleBot: { index: indexable, follow: indexable } }, openGraph: url ? { images: [ { url, width, height, alt } ] } : null }; } export default async function ProductPage(props: { params: Promise<{ handle: string }> }) { const params = await props.params; const product = await getProduct(params.handle); if (!product) return notFound(); const productJsonLd = { '@context': 'https://schema.org', '@type': 'Product', name: product.title, description: product.description, image: product.featuredImage.url, offers: { '@type': 'AggregateOffer', availability: product.availableForSale ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock', priceCurrency: product.priceRange.minVariantPrice.currencyCode, highPrice: product.priceRange.maxVariantPrice.amount, lowPrice: product.priceRange.minVariantPrice.amount } }; // If product has only one image, duplicate it to create the gallery effect const galleryImages = product.images.length === 1 ? Array(5).fill(product.images[0]).map(image => ({ url: image.url, altText: image.altText, width: image.width, height: image.height })) : product.images; return (