[object Object]

← back to build-pages

seo: canonical + og:title/desc/url + twitter:card on every shell-rendered page + 2 smoke

5c8c27dc84756ba929f95e20060217e0ed1cbbc4 · 2026-05-13 13:16:29 -0700 · SteveStudio2

Files touched

Diff

commit 5c8c27dc84756ba929f95e20060217e0ed1cbbc4
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Wed May 13 13:16:29 2026 -0700

    seo: canonical + og:title/desc/url + twitter:card on every shell-rendered page + 2 smoke
---
 server.js     | 21 ++++++++++++++++++---
 test/smoke.js |  2 ++
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/server.js b/server.js
index 5de7c65..e76861f 100644
--- a/server.js
+++ b/server.js
@@ -162,14 +162,23 @@ function esc(s) {
   return String(s).replace(/[&<>"']/g, c => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]));
 }
 
-function shell(title, body, headExtra = '') {
+function shell(title, body, headExtra = '', meta = {}) {
+  const canonical = meta.canonical || 'https://projects.agentabrams.com/';
+  const desc      = meta.desc      || 'Live build journals for every project — every commit, every line of design rationale, searchable.';
   return `<!DOCTYPE html>
 <html lang="en">
 <head>
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <title>${esc(title)}</title>
+  <meta name="description" content="${esc(desc)}">
   <meta name="color-scheme" content="light dark">
+  <link rel="canonical" href="${esc(canonical)}">
+  <meta property="og:title" content="${esc(title)}">
+  <meta property="og:description" content="${esc(desc)}">
+  <meta property="og:type" content="website">
+  <meta property="og:url" content="${esc(canonical)}">
+  <meta name="twitter:card" content="summary">
   <link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><rect width='32' height='32' rx='6' fill='%23111'/><text x='16' y='22' font-family='Georgia,serif' font-size='20' fill='%23ffd633' text-anchor='middle'>BP</text></svg>">
   <link rel="stylesheet" href="/css/site.css">
   ${headExtra}
@@ -354,7 +363,10 @@ app.get('/p/:slug', async (req, res, next) => {
         // Apply the initial ?q= from the server-rendered value field.
         if (q.value) applyFilter();
       </script>
-    `));
+    `, {
+      canonical: `https://projects.agentabrams.com/p/${req.params.slug}`,
+      desc: `${p.name} — ${p.blurb}`,
+    }));
   } catch (e) { next(e); }
 });
 
@@ -373,7 +385,10 @@ app.get('/p/:slug/c/:hash', async (req, res, next) => {
       <ul class="bp-files">${c.files.map(f => `<li><code>${esc(f)}</code></li>`).join('')}</ul>
       <h2>Diff</h2>
       <pre class="bp-diff">${esc(c.diff)}</pre>
-    `));
+    `, {
+      canonical: `https://projects.agentabrams.com/p/${req.params.slug}/c/${req.params.hash}`,
+      desc: `${c.subject} — commit in ${p.name}`,
+    }));
   } catch (e) { next(e); }
 });
 
diff --git a/test/smoke.js b/test/smoke.js
index 0e6cdca..39fe1cb 100644
--- a/test/smoke.js
+++ b/test/smoke.js
@@ -77,6 +77,8 @@ function check(name, cond, hint = '') {
   check('home: title',             /build-pages/.test(r.body));
   check('home: X-Content-Type-Options', (r.headers['x-content-type-options'] || '') === 'nosniff');
   check('home: fleet totals',      /\d+ projects · \d+ commits · \d+ design-rationale ideas/.test(r.body));
+  check('home: canonical',         /rel="canonical"/.test(r.body));
+  check('home: og:title',          /property="og:title"/.test(r.body));
 
   // 6. butlr project page renders + has commit count
   r = await fetch('/p/butlr');

← e8ee572 smoke: assert home renders fleet totals line  ·  back to build-pages  ·  seo: /sitemap.xml lists home + 4 project pages + Last-Modifi 230a1f7 →