Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion commerce/sections/Seo/SeoPDPV2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -75,6 +94,7 @@ export function loader(_props: Props, _req: Request, ctx: AppContext) {
canonical,
noIndexing,
jsonLDs,
type: "product" as const,
};
}

Expand Down
2 changes: 1 addition & 1 deletion website/components/Seo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading