Generate dynamic Open Graph images from a screenshot of the page
A dynamic Open Graph image does not need a template engine when the page already looks the way you want it shared. With the embed option the Screenshot API URL behaves like an image file, so og:image can point straight at a live capture. Blogs, docs sites, changelogs, directories and user-generated pages get a unique social card per URL without designing a single one.
Static og:image files go stale and custom renderers are work
One default banner makes every share of your site look the same, and links with a generic preview get scrolled past. A hand-made image per page fixes that for ten pages, not for ten thousand, and it is out of date the day someone edits the headline.
The usual answer is an OG image service: HTML templates, bundled fonts, a renderer on a serverless function and a cache in front of it. That is a second front end to design, deploy and keep in sync with the first one. Meanwhile the page itself is already rendered, styled and current.
The embed parameter returns one field of the response as the body, with the headers of the original resource. Set it to screenshot.url and the API URL is the PNG. Drop that URL into og:image and twitter:image and crawlers receive a capture of the page, rendered on the first request and served from the cache after that. The delivery and embedding guide shows the same URL in HTML, CSS and Markdown.
How to generate an og:image from a screenshot URL
Set the viewport to the social card size, ask for the image directly with embed, and reference the resulting URL in your meta tags. The default cache keeps the card for 24 hours.
curl 'https://api.microlink.io/?url=https%3A%2F%2Fyour-site.com%2Fblog%2Fpost&screenshot=true&meta=false&embed=screenshot.url&viewport.width=1200&viewport.height=630'embed=screenshot.url makes the response the PNG itself instead of JSON, captured at 1200×630. meta=false skips metadata detection, so the first render is faster.
<meta property="og:image" content="https://api.microlink.io/?url=https%3A%2F%2Fyour-site.com%2Fblog%2Fpost&screenshot=true&meta=false&embed=screenshot.url&viewport.width=1200&viewport.height=630" />
<meta name="twitter:image" content="https://api.microlink.io/?url=https%3A%2F%2Fyour-site.com%2Fblog%2Fpost&screenshot=true&meta=false&embed=screenshot.url&viewport.width=1200&viewport.height=630" />Crawlers fetch the API URL like any image. URL-encode the target, and check the result with the sharing debugger before you ship.
import createClient from 'microlink.io'
const microlink = createClient({
apiKey: process.env.MICROLINK_API_KEY
})
const { url } = await microlink.screenshot('https://your-site.com/blog/post', {
viewport: { width: 1200, height: 630 },
overlay: { browser: 'dark', background: '#0473e4' },
ttl: '7d',
staleTtl: 0
})overlay composes a browser frame over a background, as in the browser frame recipe. ttl and staleTtl need a Pro key, so run this from your backend or send the same options through your own proxy.
- embed Returns one field of the response as the body. screenshot.url returns the image.
- viewport 1200×630 is the common social card size. Set deviceScaleFactor to 2 for a sharper image.
- screenshot.overlay Browser window frame, light or dark, over a color, gradient or image background.
- ttl Cache lifetime from 1 minute to 31 days. Defaults to 24 hours. Pro plans.
- staleTtl Serves the cached card instantly and refreshes it in the background. Pro plans.
Keep API keys out of public og:image URLs. The free endpoint needs no key and allows 25 requests per day, which suits a small site because cache hits do not count. For production, put the request behind your own domain as described in the authentication docs.
Why a live screenshot works as a social preview image
The page is the most accurate preview of itself, and a social preview image API that already caches and serves images at the edge removes the rest of the stack.
After a viral share, crawlers and unfurlers request the same URL over and over. The cache absorbs that burst, as the traffic spikes recipe explains, and with a configurable TTL those cache hits do not count against your quota.
Pick the light or dark frame to match the page theme. The background accepts hex, rgb or rgba colors, CSS gradients or an image URL.
When not to: if the card needs text that is not on the page, such as an author or a series name, render a dedicated card and use the screenshot only as its backdrop. If the page has no og:image at all and you cannot edit it, override the metadata on the consuming side instead.
FAQ
Do social networks accept a screenshot API URL as og:image?
What size should an Open Graph screenshot be?
How often does a dynamic Open Graph image screenshot refresh?
How do I keep my API key out of the og:image screenshot URL?
Will the Open Graph screenshot include cookie banners or ads?
Solve the next problem with the same API
Screenshots with a browser frame
Screenshots under traffic spikes
Screenshots in dark mode
PDF download links and previews
Fix missing or wrong og:image
Link previews at scale
Ready to ship live social cards?
One URL per page, cached and framed. Start on the free endpoint and point your og:image at a real screenshot today.