Hwaro::Content::Seo::OgImage
Inherits Reference / Object
Auto-generate OG (Open Graph) preview images as SVG files. Produces 1200x630 SVG images with the page title, description, site name, and optional logo — all without external dependencies.
Constants
band: a full-width solid band behind the (knocked-out) title,
echoed by a thin secondary band above it.
bauhaus: flat geometric art composition on the right side.
Brand row: a small accent tick + the site name in text color.
brutalist: thick framed panel with a hard offset shadow block.
diagonal: stripe wedge in the bottom-right corner triangle
(DIAG_WEDGE_X0, HEIGHT) - (WIDTH, HEIGHT) - (WIDTH, DIAG_WEDGE_Y1).
dots: corner-weighted halftone fade; text sits lower-left.
editorial ("magazine front"): hairline rules + kicker.
framed ("invitation card"): a neutral hairline frame + accent
corner brackets; the only centered composition.
grid ("blueprint"): focal crosshair + registration marks.
halftone: print-style dot field growing toward the right edge.
--- Shared typographic design system (SVG + PNG renderers) --- One margin grid, one line-height model, one description hierarchy, and one brand treatment — so the styles differ in composition, not in sloppy metrics.
default ("masthead"): eyebrow on top, title anchored high.
--- Style families (single source of truth, shared by SVG + PNG renderers) ---
"Modern" styles are typography/panel-driven and reuse the classic background patterns. "Geometric" styles paint bold, distinctive background shapes (color blocks, bands, frames). "Signature" styles render a complete, self-contained composition (terminal window, bauhaus shapes, halftone fade) and ignore the soft text panel.
monument: accent rule ABOVE the title, brand row bottom-right.
Yield frequency inside the heavy OG PNG (and fallback SVG) rendering worker loop (see generate()).
Yielding after every single render adds scheduler overhead on
CPU-bound work. Yielding too rarely can starve the HTTP accept
fiber during serve --fast-start background OG generation.
8 is a pragmatic balance for current workloads.
Bump to invalidate incremental OG caches when the renderer's design changes without any config change (it feeds compute_config_hash). rev 2: 2026-07 typography + style redesign.
--- Geometric style layout (shared by SVG + PNG so both stay in sync) ---
split: a diagonal color block on the left; text lives on the right.
Font stacks for the SVG fallback renderer. They lead with the bundled brand faces so environments that have them render in parity with the PNG output, then degrade gracefully.
terminal: a code-editor window with a title bar + traffic lights.
waves: text centers over the calm region above the tide bands.
Class methods
Lighten (positive delta) or darken (negative) a hex color in HSL space.
Content digest of an on-disk asset (logo / background image). Replacing the file at the same path must invalidate cached OG images — hashing only the path string left stale logos baked into cached images forever.
Balanced title wrap (character-count analog of the PNG renderer's measured version): greedy wrap first; when the last line is an orphan (much shorter than the longest line), re-wrap against a tighter target so line lengths even out. Only accepted when it does not add lines.
How many title lines fit inside the fixed-height color band used by
the band style. Beyond this the title overflows the band and, being
drawn in the background color, renders invisibly off-band.
Cap a band-style title to the lines that fit the band.
Cap lines to max, marking the last kept line with an ellipsis
so the truncation is visible rather than silent.
Compute a hash of OG-relevant config properties. RENDER_REVISION is folded in so a renderer design change regenerates cached images on existing sites even though no config value changed.
Compute a hash of page content that affects OG image rendering.
True if the text contains CJK ideographs, kana, hangul, or fullwidth
forms — glyphs the bundled/system Latin fonts cannot render, so PNG
OG images would show blank "tofu" boxes unless a CJK-capable
font_path is configured.
Derive a punchy complementary color from a hex string via HSL.
Convert a file to a data URI with base64 encoding
Generate OG images for all pages that lack a custom image. Sets page.image to the generated SVG path so that og:image meta tags pick it up automatically.
partial signals that the caller is only handing in a subset
of the site's pages (e.g. --fast-start runs this once for
the priority subset and again for the deferred remainder).
In partial mode we accumulate manifest entries across calls
rather than overwriting; in full mode (default) we still
truncate so manifest entries — and the disk files they
describe — for deleted pages get pruned naturally.
Convert "#RRGGBB" to {hue(0-360), saturation(0-1), lightness(0-1)}.
Convert HSL back to a "#rrggbb" hex string.
Load the OG manifest file. Returns {config_hash, entries}.
Compute logo (x, y) for a given position string. Shared by both SVG and PNG renderers.
Mix two hex colors in RGB space (t toward other). Mirrors the
PNG renderer's lerp_color so gradient stops match across formats.
A quiet hairline color derived from the background: slightly lighter on dark backgrounds, slightly darker on light ones.
Styles that drop the classic thin top/bottom accent bars for a cleaner, more modern composition.
Normalize a user-supplied hex color to a bare 6-digit "rrggbb" form. Accepts "#rgb" shorthand (expanded to "rrggbb"), "#rrggbb", and "#rrggbbaa" (alpha is dropped). Returns nil for anything that isn't a valid hex color so callers can fall back deterministically.
Render each style's signature background: bold geometric shapes (split / band / brutalist) plus generated backdrops for the modern styles (artistic gradient, hero glow, surreal aurora, framed frame). The generated modern backdrops are skipped when a background image is present so a user photo shows through. Returns "" for plain styles.
Render a style/pattern SVG snippet based on the configured style.
Every pattern is a composition with a focal point rather than
uniform wallpaper; opacity acts as the peak alpha with internal
falloff. Mirrors the PNG renderer's render_pattern.
Render an SVG image for a page
Resolve the second color for two-tone geometric styles. Falls back to a complementary tone auto-derived from the accent color.
Save the OG manifest file.
Rotate a hex color's hue by degrees, optionally forcing a minimum
saturation so derived tones stay vivid on flat compositions.
Split text into wrappable segments: whitespace-separated words for Latin text, individual characters for CJK ranges. Public so OgPngRenderer can reuse it.