diff --git a/commerce/sections/Seo/SeoPDPV2.tsx b/commerce/sections/Seo/SeoPDPV2.tsx index 573f359c7..238824195 100644 --- a/commerce/sections/Seo/SeoPDPV2.tsx +++ b/commerce/sections/Seo/SeoPDPV2.tsx @@ -15,6 +15,13 @@ export interface Props { title?: string; /** @title Description Override */ description?: string; + /** + * @title Description Source + * @description Choose which field to use as the meta description when no Description Override is set. + * "seo" uses the SEO description from the search index (default). + * "product" uses the product's own description field, stripping HTML tags — useful when the SEO description is empty or you prefer the richer product copy. + */ + descriptionSource?: "seo" | "product"; /** * @title Disable indexing * @description In testing, you can use this to prevent search engines from indexing your site @@ -38,18 +45,30 @@ export function loader(_props: Props, _req: Request, ctx: AppContext) { const { title: titleProp, description: descriptionProp, + descriptionSource = "seo", jsonLD, omitVariants, ignoreStructuredData, } = props; + const productDescription = jsonLD?.product.description + ?.replace(/<[^>]+>/g, " ") + .replace(/\s+/g, " ") + .trim(); + + const resolvedDescription = descriptionProp || + (descriptionSource === "product" + ? productDescription || jsonLD?.seo?.description + : jsonLD?.seo?.description || productDescription) || + ctx.seo?.description || ""; + const title = renderTemplateString( titleTemplate, titleProp || jsonLD?.seo?.title || ctx.seo?.title || "", ); const description = renderTemplateString( descriptionTemplate, - descriptionProp || jsonLD?.seo?.description || ctx.seo?.description || "", + resolvedDescription, ); const image = jsonLD?.product.image?.[0]?.url; const canonical = jsonLD?.seo?.canonical @@ -75,6 +94,7 @@ export function loader(_props: Props, _req: Request, ctx: AppContext) { canonical, noIndexing, jsonLDs, + type: "product" as const, }; } diff --git a/website/components/Seo.tsx b/website/components/Seo.tsx index 08c17a04e..3133c9a4d 100644 --- a/website/components/Seo.tsx +++ b/website/components/Seo.tsx @@ -7,7 +7,7 @@ export const renderTemplateString = (template: string, value: string) => template.replace("%s", value); export type SEOSection = JSX.Element; -export type OGType = "website" | "article"; +export type OGType = "website" | "article" | "product"; export interface Props { title?: string;