← back to Thesetdecorator
TSD: add twitter:card=summary_large_image to 3 pages missing it
2343c923e40a040cce9d9a99c6dc50da0612d1fc · 2026-06-03 13:13:21 -0700 · Steve
games.html + _best-seller-detail.tpl.html (both indexable) + request-demo.html
(already noindex, harmless) had an og:image but no twitter:card, so their
Twitter shares rendered as a plain link instead of a large-image card. Added
the card after og:image; title/image fall back to OG. Idempotent
scripts/twitter-card-backfill.py; 0 indexable og:image pages still missing it,
no dupes. Invisible. Static — queued deploy.
Files touched
M public/_best-seller-detail.tpl.htmlM public/games.htmlM public/request-demo.htmlA scripts/twitter-card-backfill.py
Diff
commit 2343c923e40a040cce9d9a99c6dc50da0612d1fc
Author: Steve <steve@designerwallcoverings.com>
Date: Wed Jun 3 13:13:21 2026 -0700
TSD: add twitter:card=summary_large_image to 3 pages missing it
games.html + _best-seller-detail.tpl.html (both indexable) + request-demo.html
(already noindex, harmless) had an og:image but no twitter:card, so their
Twitter shares rendered as a plain link instead of a large-image card. Added
the card after og:image; title/image fall back to OG. Idempotent
scripts/twitter-card-backfill.py; 0 indexable og:image pages still missing it,
no dupes. Invisible. Static — queued deploy.
---
public/_best-seller-detail.tpl.html | 1 +
public/games.html | 1 +
public/request-demo.html | 1 +
scripts/twitter-card-backfill.py | 36 ++++++++++++++++++++++++++++++++++++
4 files changed, 39 insertions(+)
diff --git a/public/_best-seller-detail.tpl.html b/public/_best-seller-detail.tpl.html
index 37b97b0..520d2a6 100644
--- a/public/_best-seller-detail.tpl.html
+++ b/public/_best-seller-detail.tpl.html
@@ -13,6 +13,7 @@
<meta property="og:description" content="Production-vetted wallcovering. Preview on set, request swatch.">
<meta property="og:site_name" content="The Set Decorator">
<meta property="og:image" content="__IMAGE__">
+ <meta name="twitter:card" content="summary_large_image">
<meta property="og:type" content="product">
<script type="application/ld+json">{"@context":"https://schema.org","@type":"Product","name":"__TITLE__","brand":{"@type":"Brand","name":"__VENDOR__"},"sku":"__SKU__","image":"__IMAGE__","description":"Production-vetted wallcovering from the top 20% of Designer Wallcoverings' actual orders. Cleared for production use; fast-print delivery in LA basin."}</script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;1,400&family=Inter:wght@400;500;600&display=swap">
diff --git a/public/games.html b/public/games.html
index 1365d65..9499c2f 100644
--- a/public/games.html
+++ b/public/games.html
@@ -15,6 +15,7 @@
<meta property="og:url" content="https://thesetdecorator.com/games">
<meta property="og:site_name" content="The Set Decorator">
<meta property="og:image" content="https://thesetdecorator.com/img/hero/hero-rendered.jpg">
+ <meta name="twitter:card" content="summary_large_image">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;1,400;1,700&family=Inter:wght@400;500;600;700&display=swap">
<link rel="stylesheet" href="/css/games.css">
</head>
diff --git a/public/request-demo.html b/public/request-demo.html
index 0a76d6b..569625a 100644
--- a/public/request-demo.html
+++ b/public/request-demo.html
@@ -17,6 +17,7 @@
<meta property="og:url" content="https://thesetdecorator.com/request-demo">
<meta property="og:site_name" content="The Set Decorator">
<meta property="og:image" content="https://thesetdecorator.com/img/hero/hero-rendered.jpg">
+ <meta name="twitter:card" content="summary_large_image">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;1,400&family=Inter:wght@400;500;600&display=swap">
diff --git a/scripts/twitter-card-backfill.py b/scripts/twitter-card-backfill.py
new file mode 100644
index 0000000..fafb094
--- /dev/null
+++ b/scripts/twitter-card-backfill.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python3
+"""Idempotent: add twitter:card to pages that have an og:image but no twitter:card.
+
+Twitter renders a Card only when twitter:card is present; other fields fall back
+to the OG tags. Two pages (games.html, _best-seller-detail.tpl.html) had an
+og:image (a large hero/product image) but no twitter:* tags at all, so their
+Twitter shares rendered as a plain link. Add
+<meta name="twitter:card" content="summary_large_image"> after og:image — the
+right type for a large image. Invisible (head meta). Idempotent + reversible.
+ python3 scripts/twitter-card-backfill.py
+"""
+import os, re, glob
+
+PUB = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "public")
+
+HAS_CARD_RE = re.compile(r'name=["\']?twitter:card', re.IGNORECASE)
+OG_IMAGE_RE = re.compile(r'^([ \t]*)<meta[^>]*property=["\']?og:image["\']?[^>]*>[ \t]*\n', re.IGNORECASE | re.MULTILINE)
+
+changed, skipped, noanchor = [], [], []
+for path in sorted(glob.glob(os.path.join(PUB, "*.html"))):
+ name = os.path.basename(path)
+ html = open(path, encoding="utf-8").read()
+ if HAS_CARD_RE.search(html):
+ skipped.append(name); continue
+ m = OG_IMAGE_RE.search(html)
+ if not m:
+ noanchor.append(name); continue # no og:image — not a card candidate
+ indent = m.group(1)
+ line = f'{indent}<meta name="twitter:card" content="summary_large_image">\n'
+ html = html[:m.end()] + line + html[m.end():]
+ open(path, "w", encoding="utf-8").write(html)
+ changed.append(name)
+
+print(f"changed ({len(changed)}): {', '.join(changed) or '-'}")
+print(f"skipped/already-have-card ({len(skipped)})")
+print(f"no-og-image (skipped): {len(noanchor)}")
← c738710 backlog: loop #10 (og:site_name + WCAG autocomplete) + deplo
·
back to Thesetdecorator
·
backlog: loop #11 (twitter:card) + mark autonomous surface e b8de0cb →