Skip to content

Commit 07b52df

Browse files
fix(commerce): correctly exclude structured data for bots when disabled
- Replace boolean `ignoreStructuredData` with explicit `structuredDataControl` options - Fix bug where bots still received JSON-LD even when `ignoreStructuredData=true` - Add "always include" (default), "disable for users", and "disable for all" modes - Deprecate `ignoreStructuredData` with backward compatibility - Extract shared logic to `shouldIncludeStructuredData` utility
1 parent 30ca287 commit 07b52df

3 files changed

Lines changed: 54 additions & 6 deletions

File tree

commerce/sections/Seo/SeoPDPV2.tsx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import {
66
import { ProductDetailsPage } from "../../types.ts";
77
import { canonicalFromBreadcrumblist } from "../../utils/canonical.ts";
88
import { AppContext } from "../../mod.ts";
9+
import {
10+
shouldIncludeStructuredData,
11+
StructuredDataControl,
12+
} from "../../utils/structuredData.ts";
913

1014
export interface Props {
1115
/** @title Data Source */
@@ -23,8 +27,15 @@ export interface Props {
2327
/**
2428
* @title Ignore Structured Data
2529
* @description By default, Structured Data is sent to everyone. Use this to prevent Structured Data from being sent to your customers, it will still be sent to crawlers and bots. Be aware that some integrations may not work if Structured Data is not sent.
30+
* @deprecated Use `structuredDataControl` instead.
2631
*/
2732
ignoreStructuredData?: boolean;
33+
/**
34+
* @title Structured Data Control
35+
* @description Choose when to include JSON-LD structured data. Default sends to everyone. "disable for users" shows only to bots/crawlers. "disable for all" removes completely. Note: some third-party integrations may require structured data to function properly.
36+
* @default "always include"
37+
*/
38+
structuredDataControl?: StructuredDataControl;
2839
}
2940

3041
/** @title Product details */
@@ -41,6 +52,7 @@ export function loader(_props: Props, _req: Request, ctx: AppContext) {
4152
jsonLD,
4253
omitVariants,
4354
ignoreStructuredData,
55+
structuredDataControl = "always include",
4456
} = props;
4557

4658
const title = renderTemplateString(
@@ -63,9 +75,13 @@ export function loader(_props: Props, _req: Request, ctx: AppContext) {
6375
jsonLD.product.isVariantOf.hasVariant = [];
6476
}
6577

66-
const jsonLDs = (ignoreStructuredData && !ctx.isBot) || !jsonLD
67-
? []
68-
: [jsonLD];
78+
// Handle deprecated prop
79+
const mode = structuredDataControl ??
80+
(ignoreStructuredData ? "disable for users" : "always include");
81+
82+
const jsonLDs = shouldIncludeStructuredData(jsonLD, mode, ctx.isBot)
83+
? [jsonLD]
84+
: [];
6985

7086
return {
7187
...seoSiteProps,

commerce/sections/Seo/SeoPLPV2.tsx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import {
66
import { ProductListingPage } from "../../types.ts";
77
import { canonicalFromBreadcrumblist } from "../../utils/canonical.ts";
88
import { AppContext } from "../../mod.ts";
9+
import {
10+
shouldIncludeStructuredData,
11+
StructuredDataControl,
12+
} from "../../utils/structuredData.ts";
913

1014
export interface ConfigJsonLD {
1115
/**
@@ -16,8 +20,15 @@ export interface ConfigJsonLD {
1620
/**
1721
* @title Ignore Structured Data
1822
* @description By default, Structured Data is sent to everyone. Use this to prevent Structured Data from being sent to your customers, it will still be sent to crawlers and bots. Be aware that some integrations may not work if Structured Data is not sent.
23+
* @deprecated Use `structuredDataControl` instead.
1924
*/
2025
ignoreStructuredData?: boolean;
26+
/**
27+
* @title Structured Data Control
28+
* @description Choose when to include JSON-LD structured data. Default sends to everyone. "disable for users" shows only to bots/crawlers. "disable for all" removes completely. Note: some third-party integrations may require structured data to function properly.
29+
* @default "always include"
30+
*/
31+
structuredDataControl?: StructuredDataControl;
2132
}
2233

2334
export interface Props {
@@ -82,9 +93,14 @@ export function loader(_props: Props, _req: Request, ctx: AppContext) {
8293
});
8394
}
8495

85-
const jsonLDs = (configJsonLD?.ignoreStructuredData && !ctx.isBot) || !jsonLD
86-
? []
87-
: [jsonLD];
96+
const mode = configJsonLD?.structuredDataControl ??
97+
(configJsonLD?.ignoreStructuredData
98+
? "disable for users"
99+
: "always include");
100+
101+
const jsonLDs = shouldIncludeStructuredData(jsonLD, mode, ctx.isBot)
102+
? [jsonLD]
103+
: [];
88104

89105
return {
90106
...seoSiteProps,

commerce/utils/structuredData.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// commerce/utils/structuredData.ts
2+
export type StructuredDataControl =
3+
| "disable for users"
4+
| "disable for all"
5+
| "always include";
6+
7+
export function shouldIncludeStructuredData(
8+
jsonLD: unknown,
9+
control: StructuredDataControl = "always include",
10+
isBot: boolean,
11+
): boolean {
12+
if (!jsonLD) return false;
13+
14+
return control !== "disable for all" &&
15+
(control !== "disable for users" || isBot);
16+
}

0 commit comments

Comments
 (0)