← back to Wallco Ai
wallco.ai · /designs JSON-LD — ItemList of Products + BreadcrumbList
1d2bb76a631a2655699fd05f9fc82e69f9e00e0f · 2026-05-12 06:46:14 -0700 · SteveStudio2
ItemList was bare (name/url only) — Google saw a list of links, not a list
of products. Now each ListItem embeds a full Product (sku/productID/category/
color/material/brand/offers) so Google can render list-of-products rich
results (carousel-style snippet in SERP).
Adds BreadcrumbList as a second JSON-LD block. Adapts when a category filter
is active: Home → Designs → {cat}. Hue family derived from dominant_hex via
the same algorithm as /design/:id (rose/amber/honey/olive/sage/marine/
sapphire/mauve/plum/neutral).
Reversible: schema generation isolated; two JSON-LD blocks concatenated via
a single </script><script> seam so the existing template stays one expression.
Files touched
Diff
commit 1d2bb76a631a2655699fd05f9fc82e69f9e00e0f
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Tue May 12 06:46:14 2026 -0700
wallco.ai · /designs JSON-LD — ItemList of Products + BreadcrumbList
ItemList was bare (name/url only) — Google saw a list of links, not a list
of products. Now each ListItem embeds a full Product (sku/productID/category/
color/material/brand/offers) so Google can render list-of-products rich
results (carousel-style snippet in SERP).
Adds BreadcrumbList as a second JSON-LD block. Adapts when a category filter
is active: Home → Designs → {cat}. Hue family derived from dominant_hex via
the same algorithm as /design/:id (rose/amber/honey/olive/sage/marine/
sapphire/mauve/plum/neutral).
Reversible: schema generation isolated; two JSON-LD blocks concatenated via
a single </script><script> seam so the existing template stays one expression.
---
server.js | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 51 insertions(+), 4 deletions(-)
diff --git a/server.js b/server.js
index e6d9211..ab48b0f 100644
--- a/server.js
+++ b/server.js
@@ -1017,18 +1017,65 @@ app.get('/designs', (req, res) => {
).join(' ')
: '';
- const schema = JSON.stringify({
+ // Each ListItem embeds a full Product object so Google can render
+ // list-of-products rich results (not just bare URLs). Mirrors the
+ // per-design Product schema from /design/:id but trimmed to grid-card
+ // essentials: name, image, sku, category, brand, offers.
+ const _hueOf = (hex) => {
+ const h = (hex || '').toLowerCase();
+ if (!/^#[0-9a-f]{6}$/.test(h)) return '';
+ const r=parseInt(h.slice(1,3),16), g=parseInt(h.slice(3,5),16), b=parseInt(h.slice(5,7),16);
+ const max=Math.max(r,g,b), min=Math.min(r,g,b), s=max?(max-min)/max:0;
+ if (s<0.12) return 'neutral';
+ const hh = ((max===r ? (g-b)/(max-min)+(g<b?6:0) : max===g ? (b-r)/(max-min)+2 : (r-g)/(max-min)+4) * 60 + 360) % 360;
+ if (hh<15||hh>=345) return 'rose'; if (hh<40) return 'amber'; if (hh<60) return 'honey';
+ if (hh<90) return 'olive'; if (hh<160) return 'sage'; if (hh<200) return 'marine';
+ if (hh<250) return 'sapphire'; if (hh<290) return 'mauve'; return 'plum';
+ };
+
+ const itemList = {
"@context": "https://schema.org",
"@type": "ItemList",
"name": "Original Wallpaper Designs — wallco.ai",
+ "url": `https://wallco.ai/designs${page > 1 ? `?page=${page}` : ''}`,
"numberOfItems": total,
+ "itemListOrder": "https://schema.org/ItemListOrderDescending",
"itemListElement": slice.map((d,i) => ({
"@type": "ListItem",
"position": (page-1)*PER+i+1,
- "name": d.title,
- "url": `https://wallco.ai/design/${d.id}`
+ "item": {
+ "@type": "Product",
+ "@id": `https://wallco.ai/design/${d.id}`,
+ "name": d.title,
+ "url": `https://wallco.ai/design/${d.id}`,
+ "image": `https://wallco.ai${d.image_url}`,
+ "sku": d.handle || `wallco-${String(d.id).padStart(4,'0')}`,
+ "productID": String(d.id),
+ "category": d.category,
+ "color": _hueOf(d.dominant_hex) || undefined,
+ "material": "Wallpaper",
+ "brand": { "@type": "Brand", "name": "wallco.ai" },
+ "offers": {
+ "@type": "Offer",
+ "availability": "https://schema.org/InStock",
+ "url": `https://wallco.ai/samples?design=${d.id}`,
+ "priceCurrency": "USD",
+ "description": "Free sample available"
+ }
+ }
}))
- });
+ };
+
+ const breadcrumb = {
+ "@context": "https://schema.org",
+ "@type": "BreadcrumbList",
+ "itemListElement": [
+ { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://wallco.ai/" },
+ { "@type": "ListItem", "position": 2, "name": "Designs", "item": "https://wallco.ai/designs" }
+ ].concat(cat ? [{ "@type": "ListItem", "position": 3, "name": cat, "item": `https://wallco.ai/designs?cat=${encodeURIComponent(cat)}` }] : [])
+ };
+
+ const schema = `${JSON.stringify(itemList)}</script>\n<script type="application/ld+json">${JSON.stringify(breadcrumb)}`;
res.type('html').send(`${htmlHead({
title: `All Designs — wallco.ai | AI-Original Wallpaper & Murals`,
← 0772bf0 security — prototype-pollution + pin-spam DoS guards in src/
·
back to Wallco Ai
·
spoonflower upload — fix hydration race + add --batch CSV mo f4354f9 →