← back to Prestige Car Wash
SEO: broaden OG/Twitter + per-page canonical to /services + /contact (shared pageHtml); robust 500 fallback + canonical dup-guard — contrarian-gated
aa47ccf277006804615ae769ad7fb242972cbdc0 · 2026-07-26 16:15:25 -0700 · steve@designerwallcoverings.com
Files touched
Diff
commit aa47ccf277006804615ae769ad7fb242972cbdc0
Author: steve@designerwallcoverings.com <steve@designerwallcoverings.com>
Date: Sun Jul 26 16:15:25 2026 -0700
SEO: broaden OG/Twitter + per-page canonical to /services + /contact (shared pageHtml); robust 500 fallback + canonical dup-guard — contrarian-gated
---
server.js | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/server.js b/server.js
index 887b37f..4963f5a 100644
--- a/server.js
+++ b/server.js
@@ -445,9 +445,9 @@ function buildJsonLd() {
// Open Graph / Twitter tags for the homepage — reuses the page's own <title> and meta
// description so social previews stay in sync with on-page SEO. og:image is a real asset.
function buildSocialTags(html, pagePath) {
- // Bail if the HTML already carries og: tags (e.g. added directly to the file) so we
- // never emit duplicates that make Facebook's debugger flag the markup. (contrarian gate)
- if (/property=["']og:title["']/i.test(html)) return '';
+ // Bail if the HTML already carries og: tags OR a canonical (e.g. added directly to the
+ // file) so we never inject a duplicate that makes Facebook/Google flag the markup.
+ if (/property=["']og:title["']/i.test(html) || /<link\b[^>]*\brel=["']canonical["']/i.test(html)) return '';
const p = places() || {};
const base = (p.website || '').replace(/\/$/, '');
const url = base ? base + (pagePath || '') : ''; // page-specific canonical + og:url
@@ -481,8 +481,10 @@ function pageHtml(file, pagePath, ld) {
return html.replace('</head>', inject + '\n</head>');
}
const sendPage = (res, file, pagePath, ld) => {
+ // If tag INJECTION throws, still serve the raw page (graceful degradation). If the file
+ // itself is unreadable, sendFile's callback guarantees a clean 500 — never a hung response.
try { res.type('html').send(pageHtml(file, pagePath, ld)); }
- catch { res.sendFile(path.join(__dirname, 'public', file)); }
+ catch { res.sendFile(path.join(__dirname, 'public', file), err => { if (err && !res.headersSent) res.status(500).end(); }); }
};
app.get('/', (req, res) => sendPage(res, 'index.html', '', buildJsonLd()));
app.get('/services', (req, res) => sendPage(res, 'services.html', '/services', null));
← 1b0a067 auto-save: 2026-07-26T16:14:26 (1 files) — server.js
·
back to Prestige Car Wash
·
Analytics: GA4 gtag injection on customer pages, gated on GA 10e7bf1 →