[object Object]

← back to Stars of Design

starsofdesign: JSON-LD schema — Organization on /firms/:slug (name/website/foundingDate/address/areaServed), Person on /designers/:slug (name/jobTitle/homeLocation/knowsAbout); injected via optional json_ld locals in head.ejs partial

113ac14dfaa97dde050a9954f12e393b4a475b6b · 2026-05-12 18:37:06 -0700 · Steve Abrams

Files touched

Diff

commit 113ac14dfaa97dde050a9954f12e393b4a475b6b
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Tue May 12 18:37:06 2026 -0700

    starsofdesign: JSON-LD schema — Organization on /firms/:slug (name/website/foundingDate/address/areaServed), Person on /designers/:slug (name/jobTitle/homeLocation/knowsAbout); injected via optional json_ld locals in head.ejs partial
---
 routes/public.js        | 38 ++++++++++++++++++++++++++++++++++++++
 views/partials/head.ejs |  3 +++
 2 files changed, 41 insertions(+)

diff --git a/routes/public.js b/routes/public.js
index 5d8460b..0d4f8e1 100644
--- a/routes/public.js
+++ b/routes/public.js
@@ -76,11 +76,27 @@ router.get('/designers/:slug', (req, res, next) => {
     const d = data.bySlug(slug);
     if (!d) return res.status(404).render('public/404', { title: 'Not found — Stars of Design' });
     const designerVideos = data.videosByDesigner(slug);
+    const json_ld = {
+      '@context': 'https://schema.org',
+      '@type': 'Person',
+      name: d.name,
+      url: `https://starsofdesign.com/designers/${d.slug || slug}`,
+      ...(d.headline ? { description: d.headline } : {}),
+      ...(d.city ? {
+        homeLocation: {
+          '@type': 'Place',
+          name: d.city,
+        }
+      } : {}),
+      ...(d.styles && d.styles.length ? { knowsAbout: d.styles } : {}),
+      jobTitle: 'Interior Designer',
+    };
     res.render('public/designer', {
       title: `${d.name} — Profile, Signature Style & Wallcovering Pairings | Stars of Design`,
       meta_desc_override: `${d.name} — ${d.headline || (d.styles || []).join(', ')} interior designer based in ${d.city || 'unknown'}. Profile, era, signature works, and wallcoverings that pair with their style.`,
       designer: d,
       designerVideos,
+      json_ld,
     });
   } catch (e) { next(e); }
 });
@@ -156,10 +172,32 @@ router.get('/firms/:slug', async (req, res, next) => {
     }
     const f = await firmsLib.getFirm(slug);
     if (!f) return res.status(404).render('public/404', { title: 'Not found — Stars of Design' });
+    // JSON-LD Organization (design firm) — Schema.org primary entity is
+    // Organization with subtype `Architectural` only when applicable; we
+    // stay generic since the firm may be interiors or architecture or both.
+    const json_ld = {
+      '@context': 'https://schema.org',
+      '@type': 'Organization',
+      name: f.name,
+      url: `https://starsofdesign.com/firms/${f.slug}`,
+      ...(f.website ? { sameAs: [f.website] } : {}),
+      ...(f.founded_year ? { foundingDate: String(f.founded_year) } : {}),
+      ...(f.bio ? { description: f.bio.slice(0, 800) } : {}),
+      ...(f.city || f.state ? {
+        address: {
+          '@type': 'PostalAddress',
+          ...(f.city ? { addressLocality: f.city } : {}),
+          ...(f.state ? { addressRegion: f.state } : {}),
+          ...(f.country ? { addressCountry: f.country } : {}),
+        }
+      } : {}),
+      ...(f.areas && f.areas.length ? { areaServed: f.areas } : {}),
+    };
     res.render('public/firm', {
       title: `${f.name} — Design Firm | Stars of Design`,
       meta_desc_override: `${f.name}${f.city ? ' · ' + f.city : ''}${f.state ? ', ' + f.state : ''}${f.founded_year ? ' · founded ' + f.founded_year : ''}.`,
       firm: f,
+      json_ld,
     });
   } catch (e) { next(e); }
 });
diff --git a/views/partials/head.ejs b/views/partials/head.ejs
index f7630c5..d01f0f5 100644
--- a/views/partials/head.ejs
+++ b/views/partials/head.ejs
@@ -38,5 +38,8 @@
     })();
   </script>
   <script src="/js/theme-toggle.js" defer></script>
+  <% if (typeof json_ld !== 'undefined' && json_ld) { %>
+  <script type="application/ld+json"><%- typeof json_ld === 'string' ? json_ld : JSON.stringify(json_ld) %></script>
+  <% } %>
 </head>
 <body>

← f17b258 starsofdesign: GET /favicon.ico fallback — returns public/fa  ·  back to Stars of Design  ·  starsofdesign: JSON-LD Person schema on /clients/:slug (DW c 044e06c →