import type { Product, ShippingSummaryEntry } from 'brainerce'; import { buildProductJsonLd, buildBreadcrumbJsonLd, buildProductFaqJsonLd } from 'brainerce'; import { getNonce } from '@/core/lib/nonce'; import { getCanonicalSiteUrl } from '@/core/lib/site-url'; import { resolveCurrency } from '@/core/lib/resolve-currency'; interface ProductJsonLdProps { product: Product; url: string; currency?: string; /** From `storeInfo.shipping` — real flat-rate/free zones only. Omitted entirely when unset, never fabricated. */ shipping?: ShippingSummaryEntry[]; } /** * Product + BreadcrumbList structured data for a product detail page (PDP). * * Uses the SDK's `buildProductJsonLd` — NEVER hand-roll the schema object * here. The builder owns the availability mapping (InStock / BackOrder / * OutOfStock from the backend's pre-computed inventory flags), the * Offer/AggregateOffer split, identifier emission (gtin/mpn/sku), shipping * details, and the aggregateRating gating; a local copy WILL drift from it. * The ` or inject HTML. function serializeJsonLd(value: unknown): string { return JSON.stringify(value) .replace(//g, '\\u003e') .replace(/&/g, '\\u0026'); }