OG image generation
How Open Graph images are generated at build time using satori and sharp, composited onto a watercolor background.
Every published post has an Open Graph image — a 1200×627 PNG that appears when the URL is shared on LinkedIn, Slack, or in a browser preview. They’re generated at build time, not dynamically.
The pipeline
scripts/generate-og-images.cjs runs after a build. It processes four collections: articles, field-notes, seeds, and jottings.
For each post:
- Parse frontmatter to extract
title,description, anddraftflag - Skip draft posts
- Build a text overlay as a React-like element tree using satori (text → SVG)
- Composite the text SVG on top of a pre-rendered background PNG using sharp
- Save to
public/images/og/<collection>/<slug>.png
The background
scripts/og-bg.png is a pre-rendered 1200×627 PNG — a sage green wash with a watercolor leaf in the upper right. It’s generated once and reused for every image.
Text layout
// Inside buildTextOverlay()
{
type: 'div',
props: {
style: {
padding: '60px 80px',
display: 'flex',
flexDirection: 'column',
gap: '20px',
},
children: [
// Title: dark, large, Lora-style serif
// Description: muted, smaller
// Site label: "maaike.ai" bottom-left
]
}
}
Satori converts this element tree to an SVG. Sharp composites it over the background at full opacity.
Output path
public/images/og/articles/my-post-slug.png
public/images/og/field-notes/my-field-note.png
In BaseLayout.astro, the OG image meta tag uses:
const ogImage = `/images/og/${collection}/${slug}.png`;
const socialImage = ogImage
? new URL(ogImage, 'https://www.maaike.ai').href
: 'https://www.maaike.ai/images/og-default.png';
If no image exists (collections not in the generation script, or unpublished drafts), it falls back to og-default.png.
CopyCardImage component
CopyCardImage.astro (in the post footer share section) lets readers copy the OG image to their clipboard as a PNG — for pasting directly into LinkedIn without uploading. It reads the pre-generated file at the imagePath prop and uses the Clipboard API with a Canvas fallback.
When to regenerate
OG images need to be regenerated when:
- A post title or description changes
- A new post is published
The /publish skill handles this automatically as part of the publishing workflow.