[object Object]

← back to Thesetdecorator

TSD SEO: inject Home>PageTitle BreadcrumbList JSON-LD on interior PUBLIC_PAGES (DTD verdict A)

77538fb368fb0caf1bb6e68d114d3d7c395736bf · 2026-06-03 09:54:16 -0700 · Steve

Extends renderWithSEO's generic else-branch to add a 2-crumb BreadcrumbList
(Home > PageTitle, name from <title> minus site suffix, entities decoded)
alongside the canonical. Covers the ~14 flat interior pages that had no
structured data (about, resources, itinerary, mood-board, for-studios, etc.).
catalog/best-sellers unchanged (their own if-branches). Verified on a free
port: breadcrumb present + valid JSON + correct names + canonical still single;
no double-markup. Local only; rides the queued deploy.

Files touched

Diff

commit 77538fb368fb0caf1bb6e68d114d3d7c395736bf
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed Jun 3 09:54:16 2026 -0700

    TSD SEO: inject Home>PageTitle BreadcrumbList JSON-LD on interior PUBLIC_PAGES (DTD verdict A)
    
    Extends renderWithSEO's generic else-branch to add a 2-crumb BreadcrumbList
    (Home > PageTitle, name from <title> minus site suffix, entities decoded)
    alongside the canonical. Covers the ~14 flat interior pages that had no
    structured data (about, resources, itinerary, mood-board, for-studios, etc.).
    catalog/best-sellers unchanged (their own if-branches). Verified on a free
    port: breadcrumb present + valid JSON + correct names + canonical still single;
    no double-markup. Local only; rides the queued deploy.
---
 server.js | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/server.js b/server.js
index 2715d20..cadc869 100644
--- a/server.js
+++ b/server.js
@@ -297,7 +297,21 @@ function renderWithSEO(slug, req) {
     ]);
     injected = `\n<link rel="canonical" href="${escAttr(pageUrl)}">\n<script type="application/ld+json">${JSON.stringify(itemList)}</script>\n<script type="application/ld+json">${JSON.stringify(crumbs)}</script>\n`;
   } else {
-    injected = `\n<link rel="canonical" href="${escAttr(pageUrl)}">\n`;
+    // Generic interior page: canonical + a Home > PageTitle BreadcrumbList. These
+    // pages are flat (one level under home), so a 2-crumb trail is accurate
+    // navigational markup (not over-markup). Page name comes from the <title>,
+    // minus the " — The Set Decorator" site suffix, with the few HTML entities
+    // that appear in titles decoded for the JSON-LD string.
+    const rawTitle = (html.match(/<title>([^<]*)<\/title>/i) || [])[1] || slug;
+    const pageName = rawTitle
+      .split(/\s+[—–|]\s+/)[0]
+      .replace(/&amp;/g, '&').replace(/&#39;/g, "'").replace(/&quot;/g, '"')
+      .trim() || slug;
+    const crumbs = buildBreadcrumbJSONLD([
+      { name: 'The Set Decorator', url: CANONICAL_BASE + '/' },
+      { name: pageName, url: pageUrl },
+    ]);
+    injected = `\n<link rel="canonical" href="${escAttr(pageUrl)}">\n<script type="application/ld+json">${JSON.stringify(crumbs)}</script>\n`;
   }
   // Strip any static <link rel="canonical"> already in the .html template before
   // injecting ours. Several PUBLIC_PAGES carry a static canonical in the .html

← 619da85 backlog: loop #4 (canonical-dedup fix) + queue deploy for St  ·  back to Thesetdecorator  ·  backlog: loop #5 (interior breadcrumbs) + catalog ItemList d 9ebedbd →