← 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
M routes/public.jsM views/partials/head.ejs
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 →