[object Object]

← back to Naturaltextilewallpaper

seo: add per-page canonical + Open Graph + Twitter card (headHTML threads canonical+ogImage; index collapses facets to material per DTD-B, detail uses redacted product slug)

13c12848aa4d6b18cb397993aad00cf309efbe69 · 2026-06-04 08:09:49 -0700 · Steve

Files touched

Diff

commit 13c12848aa4d6b18cb397993aad00cf309efbe69
Author: Steve <steve@designerwallcoverings.com>
Date:   Thu Jun 4 08:09:49 2026 -0700

    seo: add per-page canonical + Open Graph + Twitter card (headHTML threads canonical+ogImage; index collapses facets to material per DTD-B, detail uses redacted product slug)
---
 server.js | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/server.js b/server.js
index 71932e7..3291f11 100644
--- a/server.js
+++ b/server.js
@@ -317,7 +317,7 @@ const GTAG = GA_ID ? `
   <script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag('js',new Date());gtag('config','${GA_ID}');</script>
 ` : '';
 
-function headHTML(title, description) {
+function headHTML(title, description, canonical='', ogImage='') {
   return `<!DOCTYPE html>
 <html lang="en">
 <head>
@@ -328,6 +328,11 @@ function headHTML(title, description) {
   </script>
   <title>${title}</title>
   <meta name="description" content="${description}">
+  ${canonical?`<link rel="canonical" href="${canonical}">\n  `:''}<meta property="og:type" content="website">
+  <meta property="og:site_name" content="Natural Textile Wallpaper">
+  <meta property="og:title" content="${title}">
+  <meta property="og:description" content="${description}">
+  ${canonical?`<meta property="og:url" content="${canonical}">\n  `:''}${ogImage?`<meta property="og:image" content="${ogImage}">\n  `:''}<meta name="twitter:card" content="${ogImage?'summary_large_image':'summary'}">
   <meta name="theme-color" content="#f5ede0" media="(prefers-color-scheme: light)">
   <meta name="theme-color" content="#1a1410" media="(prefers-color-scheme: dark)">
   ${GTAG}
@@ -570,7 +575,9 @@ function renderIndex(q, material, sort) {
 
   return headHTML(
     `Natural Textile Wallpaper — Free Memo Samples from Designer Wallcoverings | ${matLabel}`,
-    `Shop linen, jute, raffia, sisal, hemp, grasscloth and woven natural-fiber wallcoverings. Free memo samples, trade service, and expert hand-holding from Designer Wallcoverings.`
+    `Shop linen, jute, raffia, sisal, hemp, grasscloth and woven natural-fiber wallcoverings. Free memo samples, trade service, and expert hand-holding from Designer Wallcoverings.`,
+    'https://naturaltextilewallpaper.com/' + (material && material!=='all' ? `?material=${encodeURIComponent(material)}` : ''),
+    (heroProduct && heroProduct.image_url) ? IMGP.proxyImg(heroProduct.image_url) : ''
   ) + headerHTML(q, material, sort) + `
 
   ${q==='' && material==='all' ? `
@@ -761,7 +768,9 @@ function renderDetail(p, matLabel) {
   const images = (p.images && p.images.length > 1 ? p.images : [p.image_url]).map(IMGP.proxyImg);
   return headHTML(
     `${p.title} — Free Memo Sample | Natural Textile Wallpaper`,
-    `Explore ${p.title} — a ${matLabel} wallcovering available with free memo samples and trade service from Designer Wallcoverings. Order yours today.`
+    `Explore ${p.title} — a ${matLabel} wallcovering available with free memo samples and trade service from Designer Wallcoverings. Order yours today.`,
+    `https://naturaltextilewallpaper.com/p/${encodeURIComponent(redactVendorSlug(p.handle))}`,
+    images[0] || ''
   ) + headerHTML() + `
   <div class="detail-wrap">
     <nav class="breadcrumb">

← 2f5369f Scrub residual vendor names from products.json (title/vendor  ·  back to Naturaltextilewallpaper  ·  Recompute aesthetic from tags via classifyAesthetic (was deg d479737 →