Open Graph Images — 279 Pages, Build-Time Generation, Gated Deployment
Why This Matters
API documentation gets shared. A link to an endpoint page dropped in Slack, a guide shared on LinkedIn, a Stack Overflow answer pointing at the webhooks reference — all of them render a preview card. Without og:image, that card is a blank rectangle with a URL. With it, the SpeyBooks brand and the specific page content appear in the preview.
More than branding, this closes the last significant SEO gap on docs.speybooks.com. The July audit flagged og:image missing on all 280 pages as the only incomplete OG tag coverage. It is now complete, and the G4 gate in the deploy pipeline asserts it stays that way.
Open Graph Image Generation
Build-time generation with Satori and Sharp
279 OG cards generated at build time — one per page — before astro build runs. Cards are written to public/og/ and baked into dist/ by Astro’s static file handling automatically.
-
Card design Dark theme matching the SpeyDocs UI (
#0f172abackground,#e2e8f0text,#2563ebaccent). SpeyBooks logo top-left, section badge top-right, title centre, description below,docs.speybooks.comand the “Accounting as Code · UK Developer API” tagline in the footer. A 4px accent bar runs the full left edge. -
Page-kind differentiation Endpoint pages carry a coloured method badge (GET/POST/PUT/PATCH/DELETE, matching the CSS variables) and the API path in monospace beneath it. Resource landing pages carry the tag description as the subtitle. Schema pages carry a generic schema description. Guide and preamble pages carry the page description from the IR.
-
Content-addressed cache Cards are cached in
.og-cache/by SHA-256 hash of their inputs (title, description, section, method, path) plus aTEMPLATE_VERSIONstring. Identical inputs reuse the cached PNG with no Satori call. On the first run all 279 generated in under 30 seconds; subsequent runs complete in under 3 seconds from cache. -
Font handling Satori does not support WOFF2 or variable fonts. Inter Regular and Bold are fetched as static-weight WOFF from Google Fonts on the first build and cached to
public/fonts/. Subsequent builds load from disk with no network call.
Meta tags
Five tags added to Layout.astro for all pages:
og:image https://docs.speybooks.com/og/{slug}.png
og:image:width 1200
og:image:height 630
twitter:card summary_large_image
twitter:image https://docs.speybooks.com/og/{slug}.png
Slug derived from the page route using the same replace logic as the generator (/api/v1/accounts/ → api--v1--accounts.png), so route and image are always in sync.
Deploy Pipeline
G4 assertion extended
The existing G4 gate (281 pages; 202 endpoint pages match spec; 18 schemas) now also asserts 279 OG images. A deploy that fails to generate OG images fails G4 and does not proceed to the live swap.
OG phase added
A dedicated OG phase runs between G2 (parser verification) and G3 (Astro build). Output is logged with a count and timing. On cache-hit runs the phase completes in 2 seconds.
SEO Fixes
Legacy redirect for pre-refactor guide URLs
AhrefsBot was returning 404 on /guides/dividends and /guides/csv-import — URLs from before the /api/ prefix was added during the SpeyDocs refactor. A pattern redirect added to nginx:
location ~ ^/guides/(.*)$ {
return 301 /api/guides/$1;
}
Single hop, no chain. Verified with curl before reload.
Operational Impact
- 279 pages now carry correct
og:image,og:image:width,og:image:height,twitter:card, andtwitter:imagetags — 0 before this release. - OG coverage verified at opengraph.xyz: 12/12 meta tags passing, correct preview card rendering.
- Build time addition: under 3 seconds on cache-hit runs; under 30 seconds on full regeneration.
- G4 gate extended — OG image count is now a deploy-blocking assertion.
- Two legacy guide URLs now return 301 instead of 404.
Files Changed
Backend: None.
Docs site:
scripts/generate-og-images.ts— new; Satori + Sharp build-time generatorsrc/lib/og-cache.ts— new; content-addressed cache (ported from speytech.com)src/layouts/Layout.astro—og:image,og:image:width/height,twitter:card,twitter:imageaddeddeploy.sh— OG phase added; G4 assertion extended to include OG image countpublic/fonts/Inter-Regular.woff— new; cached from Google Fonts, required by Satoripublic/fonts/Inter-Bold.woff— new; cached from Google Fonts, required by Satoripackage.json/pnpm-lock.yaml—satori,@resvg/resvg-js,sharp,tsxadded as dev dependencies.gitignore—public/og/excluded (generated at build time, not committed)
nginx (docs.speybooks.com):
- Legacy
/guides/*→/api/guides/*redirect pattern added
OG image coverage completes the open meta-tag audit from the June 2026 SEO review. The next docs pass addresses the five pages with missing <h1> tags in the SpeyDocs template.