@decocms/blocks 7.26.1 → 7.26.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decocms/blocks",
3
- "version": "7.26.1",
3
+ "version": "7.26.2",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=24"
@@ -271,19 +271,33 @@ describe("commerce SEO section schemas", () => {
271
271
  expect(props.jsonLD.hide).toBe(true);
272
272
  });
273
273
 
274
- it("registers the sections so existing pages resolve, without polluting the picker", () => {
274
+ it("always registers the defs + manifest blocks so existing pages resolve", () => {
275
275
  const meta = composeMeta(emptySiteMeta());
276
276
  for (const key of [
277
277
  "commerce/sections/Seo/SeoPLPV2.tsx",
278
278
  "commerce/sections/Seo/SeoPDPV2.tsx",
279
279
  ]) {
280
- // Registered as a manifest block + def → the SEO editor can resolve a
281
- // schema for a page already on this type.
282
280
  expect(meta.manifest.blocks.sections).toHaveProperty(key);
283
281
  expect(meta.schema.definitions).toHaveProperty(b64(key));
284
- // But deliberately NOT offered as a new pickable section everywhere
285
- // (legacy commerce types have no component in start).
286
- expect(meta.schema.root.sections.anyOf).not.toContainEqual(b64Ref(key));
282
+ }
283
+ });
284
+
285
+ it("offers them as page.seo options only on a commerce site", () => {
286
+ // "commerce site" = product-list loaders registered (the signal
287
+ // buildFrameworkSections gates the picker on). The key must match
288
+ // inferLoaderTags so it is tagged "product-list".
289
+ registerAppSchemas({
290
+ namespace: "vtex",
291
+ loaders: {
292
+ "vtex/loaders/test/ProductListForSeoPicker.ts": { type: "object", properties: {} },
293
+ },
294
+ });
295
+ const meta = composeMeta(emptySiteMeta());
296
+ for (const key of [
297
+ "commerce/sections/Seo/SeoPLPV2.tsx",
298
+ "commerce/sections/Seo/SeoPDPV2.tsx",
299
+ ]) {
300
+ expect(meta.schema.root.sections.anyOf).toContainEqual(b64Ref(key));
287
301
  }
288
302
  });
289
303
  });
package/src/cms/schema.ts CHANGED
@@ -736,6 +736,12 @@ function buildFrameworkSections(sectionAnyOf: any[]) {
736
736
  const manifestBlocks: Record<string, any> = {};
737
737
  const extraAnyOf: any[] = [];
738
738
 
739
+ // A site is "commerce" when it registered product-list loaders (same signal
740
+ // wrapResolvableProperties uses). Gates whether the commerce SEO section types
741
+ // below are offered as pickable page.seo options — a blog site should not see
742
+ // "Product listing SEO" in the SEO type dropdown.
743
+ const hasCommerce = getProductListLoaderKeys().length > 0;
744
+
739
745
  // --- website/sections/Rendering/Lazy.tsx ---
740
746
  const LAZY_TYPE = "website/sections/Rendering/Lazy.tsx";
741
747
  const lazyKey = toBase64(LAZY_TYPE);
@@ -842,11 +848,10 @@ function buildFrameworkSections(sectionAnyOf: any[]) {
842
848
  // data-source block-ref set once when the page is created; it round-trips via
843
849
  // the form (kept `hide`) rather than being re-picked in the SEO panel.
844
850
  //
845
- // NOT pushed to `extraAnyOf`: unlike the website Seo sections these are legacy
846
- // deco-cx types with no component in start, so we only register the def +
847
- // manifest block (enough for the SEO editor to resolve a schema for pages
848
- // already on these types) without offering them as a new pickable section on
849
- // every — including non-commerce — site.
851
+ // The def + manifest block are always registered so the SEO editor can resolve
852
+ // a schema for pages already on these types. They are added to `extraAnyOf`
853
+ // (offered as a selectable page.seo type) only on commerce sites, so a blog
854
+ // does not get "Product listing SEO" in its SEO type dropdown.
850
855
  const SEO_PLP_V2_TYPE = "commerce/sections/Seo/SeoPLPV2.tsx";
851
856
  const seoPlpV2Key = toBase64(SEO_PLP_V2_TYPE);
852
857
  definitions[seoPlpV2Key] = {
@@ -882,6 +887,7 @@ function buildFrameworkSections(sectionAnyOf: any[]) {
882
887
  $ref: `#/definitions/${seoPlpV2Key}`,
883
888
  namespace: "commerce",
884
889
  };
890
+ if (hasCommerce) extraAnyOf.push({ $ref: `#/definitions/${seoPlpV2Key}` });
885
891
 
886
892
  // --- commerce/sections/Seo/SeoPDPV2.tsx ---
887
893
  // Product-details SEO. Studio "pdp" mode counterpart of the PLP section above.
@@ -914,6 +920,7 @@ function buildFrameworkSections(sectionAnyOf: any[]) {
914
920
  $ref: `#/definitions/${seoPdpV2Key}`,
915
921
  namespace: "commerce",
916
922
  };
923
+ if (hasCommerce) extraAnyOf.push({ $ref: `#/definitions/${seoPdpV2Key}` });
917
924
 
918
925
  // --- website/flags/multivariate/section.ts ---
919
926
  const MV_SECTION_TYPE = "website/flags/multivariate/section.ts";