// cornerstone
Screenshot to OG Image — the only generator that uses your real page
Every other OG-image tool asks you to redesign your page in a template editor (Placid, Bannerbear, OpenGraph.xyz) or rebuild it in JSX (@vercel/og). Linkshot screenshots your live page at 1200×630 and turns the result into your og:image. No parallel template, no drift, full TailwindCSS.
The 30-second answer
Drop one meta tag in your <head> with your page URL as the parameter. Linkshot screenshots that page, returns a 1200×630 PNG, caches it on Cloudflare's edge. Every page on your domain gets an OG image automatically — including new pages you have not even written yet.
<meta
property="og:image"
content="https://uselinkshot.com/api/og/v1/<TEMPLATE_ID>?url=<PAGE_URL>"
/>
{/* Optional: hide nav and cookie banner only in the screenshot */}
<nav className="linkshot:hidden">…</nav>
<div className="cookie-banner linkshot:hidden">…</div>
{/* Optional: restyle the hero only at capture time */}
<h1 className="text-3xl linkshot:text-6xl linkshot:text-center">
{post.title}
</h1>Why screenshot-based OG generation matters
The dominant OG-image generation patterns all share a problem: they decouple the OG image from the page it represents.
- Template editors (Placid, Bannerbear, OpenGraph.xyz, MyOGImage) ask you to redesign your hero in their UI. Two design systems, two sources of truth, silent drift after every site redesign.
- JSX-based generators (@vercel/og, sveltekit-og) ask you to rebuild your hero as JSX inside an API route, in a CSS subset (Satori) that does not support Grid, container queries, or arbitrary TailwindCSS values.
- Generic screenshot APIs (Urlbox, ScreenshotOne, Microlink) screenshot URLs but treat OG as one use case among many. No 1200×630 default, no modifier-based design control, no OG-aware caching.
All of these create the same outcome: when your real page changes, your OG image silently shows the old version until someone remembers to update it. The drift is the symptom; the cause is having two design systems for one piece of UI.
How Linkshot solves it
Real Chromium, real page
Linkshot screenshots your actual page using a real headless Chromium browser. JavaScript executes, fonts load from your real markup, every CSS feature works exactly as in your dev tools.
linkshot: TailwindCSS modifier
Add capture-only styles next to the elements they target. class="linkshot:hidden" to hide a navbar at capture, class="linkshot:text-6xl linkshot:text-center" to restyle a hero. Your live page is untouched; your OG looks polished.
Edge caching that does not count cache hits
The first render for a URL takes a couple of seconds; every subsequent fetch (social-media crawlers, repeated unfurls) is served from Cloudflare's edge instantly and does not consume your monthly quota.
One class, capture-only, no drift
The linkshot: modifier activates only during screenshot capture. Your live page is untouched and your screenshot styles never drift from your real markup, because they live on the real markup.
<nav className="linkshot:hidden">…</nav>
<div className="cookie-banner linkshot:hidden">…</div>
<h1 className="text-3xl linkshot:text-6xl linkshot:text-center">
{post.title}
</h1>Three steps to ship
Add your domain
Register the domain you want OG images generated from. Takes 30 seconds in the dashboard.
Drop one meta tag
Put the Linkshot URL in your og:image meta tag with the page URL as the parameter. Works on every framework that renders HTML.
Add linkshot: classes (optional)
Sprinkle linkshot:hidden, linkshot:text-6xl, etc. on the elements you want hidden or restyled at capture. Your live page is untouched.
Compare to other approaches
Frequently asked questions
What is "screenshot to OG image"?
It is the workflow where your og:image meta-tag URL points at a screenshot of the actual page being shared, instead of a static template image you designed separately. The result: when your real page changes, your OG image changes automatically. No template to maintain, no drift.
Why use a screenshot instead of a template?
Because the page is the design. If you spent time on a hero, the OG image should show that hero, not a parallel JSX or template-editor approximation. Screenshot-based OG generation eliminates the parallel-design problem entirely — there is only one source of truth for what your page looks like.
Will the screenshot include my navbar, cookie banner, or chat widget?
Only if you want it to. Linkshot ships a `linkshot:` TailwindCSS modifier — add `class="linkshot:hidden"` to any element and it disappears only during screenshot capture. Your live site is untouched.
Is screenshot generation slow?
The first render for a given URL takes a couple of seconds. Linkshot caches the result on Cloudflare's edge globally, so every subsequent fetch (Slack unfurl, Facebook scrape, X preview) is served instantly from the nearest edge node.
What about JavaScript-rendered content?
Linkshot uses real headless Chromium, so it executes JavaScript before capture. Client-side rendered content, hydrated React, lazy-loaded images, dynamic charts — all captured exactly as a real browser would render them.
How do I migrate from a template-based OG generator?
Replace the static image URL in your og:image meta tag with a Linkshot URL that includes your page URL. Add `linkshot:hidden` to anything you don't want in the screenshot. Done. The bigger work is mental — stop maintaining a parallel template and start treating the live page as the source of truth.
What output sizes are supported?
Linkshot defaults to 1200×630 — the standard OG image dimension used by Facebook, X, LinkedIn, Slack, Discord, iMessage, and most link-unfurling platforms. Other sizes are available via per-template configuration.
Does this work outside Next.js?
Yes. Linkshot is a hosted API — your og:image meta tag is just a URL. It works identically on Astro, Remix, SvelteKit, Nuxt, TanStack Start, Hono, Hugo, Jekyll, WordPress, Shopify, Webflow, Framer, plain HTML, or any backend that renders a meta tag.
Ship your first screenshot-based OG image
One meta tag, every page covered, full TailwindCSS — $9/mo with a 7-day free trial that needs no card.
7-day free trial · no credit card required