Generates the preview image that appears when a link is shared, from a template and the page title, so every page has a card without a designer.
Build me share-image generation that replaces OG Image: every page gets a preview card, from a template and its own title, with no designer involved. STACK - Node 20+ with Fastify, or an Astro endpoint if the site is already Astro - satori for layout and @resvg/resvg-js for rasterising, sharp for post-processing. No headless browser — it is fifty times heavier for the same result - SQLite through better-sqlite3 only if you want a cache index and usage counts - Caddy in front THE SIZE AND WHAT IT MEANS - 1200 by 630, which every platform crops from. Design inside a safe area, because the corners get cut on some of them - The card will most often be seen at about 300 pixels wide in a feed, on a phone. That is the design constraint: if the title is not readable at a quarter size, the card has failed - So: very large type, high contrast, three elements at most. A card that looks elegant at full size and unreadable in a thumbnail is the most common mistake in this category THE TEMPLATE - Templates as functions returning a satori node tree, in your own repository, versioned with the site - Each takes a small object: title, kind, an optional label, an optional avatar, an optional number - Layout with flexbox only — satori supports a subset of CSS deliberately, and fighting it wastes a day. Read what it supports before designing - Brand marks and background artwork embedded as inline SVG or as a base64 image, never fetched at render time - One template per page kind: an article, a category, a product, the home page. Four is usually enough TEXT FITTING, WHICH IS THE ACTUAL WORK - Titles vary from four characters to a hundred and forty. The template must handle both without clipping and without a two-word line in forty-point type - Shrink to fit by binary search on the rendered height, not by counting characters — a character count is wrong the moment the title has an M or an i in it - A minimum size below which you truncate at a word boundary with an ellipsis, deliberately chosen - Line clamping with a real measurement, and balanced line breaks so the last line is not one word - Test with the ten worst titles on your site, plus one that is a single very long unbroken word FONTS - Self-hosted WOFF or TTF files loaded from disk at boot. Never from a CDN at render time - Satori needs the font data itself, and it does not do fallback chains for you: declare a fallback font that covers the scripts you might receive, or non-Latin titles render as empty boxes - Emoji need their own font or an image substitution. Decide, and test with a title containing one, because emoji in titles are extremely common SERVING IT - Generate at build time where the set of pages is known. Nothing runs at request time, nothing can fail when a link is shared, and the cost is zero - Generate on demand only for pages that cannot be enumerated, and then cache immutably: the URL carries a content hash, and the file is written once - Return the correct content type with a long cache lifetime and an ETag - A cache directory keyed by template version and payload hash, so changing a template regenerates everything and changing nothing regenerates nothing THE TAGS - og:image with an absolute URL, og:image:width, og:image:height, og:image:alt, and twitter:card set to summary_large_image - og:url must be the canonical absolute URL. Some platforms fetch that URL rather than the one shared, so a mismatch means they render a different page's card - Platforms cache aggressively. Changing an image at the same URL often does nothing for days — put a version parameter in the URL when you need a new card to appear, and remember that some platforms strip unfamiliar query parameters - Test with each platform's own preview inspector, and be aware their previews sometimes lie about what a real post will render WHAT TO PUT ON THE CARD - The title, large. The site name, small. One piece of context — a category, a date, a verdict, a number - Not the full description, which nobody reads at thumbnail size - Not a stock photograph. A typographic card with your colours is more distinctive in a feed than any photograph - Contrast measured, not eyeballed. Text at that size still needs to clear the ratio against its background OPERATIONS - .env: BASE_URL, CACHE_PATH, FONT_PATH, TEMPLATE_VERSION - A CLI that regenerates everything, printing what changed - A check in CI that every page has an image and that none is over the size limit platforms accept - Health endpoint that renders one card through the real path WHAT MATTERS MOST Text fitting and generating at build time. Get the binary-search shrink working against your worst titles, then move generation into the build so nothing can fail at the moment somebody shares a link. A card that renders blank on the one post that gets attention is the only failure mode that counts here. Give me the repository, the templates, the build-time generator, the on-demand endpoint, and a README with the platform quirks and cache behaviour written down.
What you lose
- Templates designed to read at thumbnail size, which is harder than it looks
- Font loading and text fitting handled for arbitrary titles
- A hosted endpoint with caching, so nothing runs at request time
If you would rather not build
- Vercel OG, if you deploy there
- A hand-made image per page, for a small site
What it costs
as published on their pricing page
| Plan | Billed monthly | Billed yearly | Last read |
|---|---|---|---|
| — | $12/mo | — | — |
Their pricing page is where these came from. Seeing a different price? Tell us.
The escape hatch
open source · no votes, no paid placement
satori
$0Renders JSX and CSS to SVG, which is how most card generators work.
vercel/satorifree · open source
Why this verdict
our own opinion · changed only by a person
95/100
Verdict yes at 95. satori and resvg do the work; the only real craft is making the headline readable at thumbnail size.
History
tracked since 10 Aug 2026 · nothing is ever overwritten
Questions about OG Image
answered from the record above
Is OG Image free?
No — the plan we track is $12 a month. Around $12/month billed monthly for generated social preview images.
Can you replace OG Image by building your own?
YES. Replaceable in one session with an AI coding agent. Replacement score 95 out of 100, build time one session. Read what you lose before you decide.
How much does OG Image cost?
$12 a month on Pro — $144 a year. Recorded 10 Aug 2026.
What do you lose by replacing OG Image?
Templates designed to read at thumbnail size, which is harder than it looks; Font loading and text fitting handled for arbitrary titles; A hosted endpoint with caching, so nothing runs at request time. If any of those carry weight for you, keep paying.
Is there an open-source alternative to OG Image?
Yes: satori, resvg-js. The prompt on this page is for when you want it your way instead.
Related entries
same category first, most replaced first
Every week, something stops being worth paying for.
New verdicts, prices that moved, entries added. One email a week. Unsubscribe in one click. Nothing is being sent yet — your address is kept here, and the first issue is the first thing it is used for.
free forever · no tracking pixel · stored here, never passed to anyone

