
Free OG image generator
Compose a 1200×630 card, watch it update, download the PNG, or copy the Next.js file for the template you picked.
- Free
- No signup
- Nothing stored
/api/og-tool?template=blog&title=Ship+the+post+people+actually+share&subtitle=A+readable+1200%C3%97630+card+for+every+essay.&author=Waseem+Anjum&font=syne&background=%230C0C0C&foreground=%23E7EEF3&accent=%238FB4C9
Get the code
import { ImageResponse } from "next/og"
export const alt = "Ship the post people actually share"
export const size = { width: 1200, height: 630 }
export const contentType = "image/png"
// Template: blog
export default async function Image() {
const font = await loadFont("Syne")
return new ImageResponse(
(
<div style={{ width: "100%", height: "100%", display: "flex", flexDirection: "column", background: "#0C0C0C", color: "#E7EEF3", fontFamily: "Syne", padding: "64px 72px 64px 84px" }}>
<div style={{ position: "absolute", left: 0, top: 0, width: 16, height: "100%", background: "#8FB4C9", display: "flex" }} />
<div style={{ display: "flex", justifyContent: "space-between" }}>
<div style={{ display: "flex", fontSize: 22, letterSpacing: 6, fontWeight: 700, color: "#8FB4C9" }}>BLOG</div>
<div style={{ display: "flex", fontSize: 26, color: "rgba(231, 238, 243, 0.72)" }}>{"Waseem Anjum"}</div>
</div>
<div style={{ display: "flex", flexDirection: "column", flexGrow: 1, justifyContent: "flex-end" }}>
<div style={{ display: "flex", fontSize: 70, fontWeight: 700, lineHeight: 1.02, letterSpacing: -2, maxWidth: 980 }}>{"Ship the post people actually share"}</div>
<div style={{ display: "flex", marginTop: 22, fontSize: 30, lineHeight: 1.35, color: "rgba(231, 238, 243, 0.72)", maxWidth: 900 }}>{"A readable 1200×630 card for every essay."}</div>
</div>
<div style={{ display: "flex", alignItems: "center", marginTop: 36 }}>
<div style={{ width: 72, height: 8, borderRadius: 99, background: "#8FB4C9", display: "flex" }} />
<div style={{ display: "flex", marginLeft: 16, fontSize: 22, letterSpacing: 2, color: "rgba(231, 238, 243, 0.72)" }}>1200 × 630</div>
</div>
</div>
),
{
...size,
fonts: font
? [{ name: "Syne", data: font, style: "normal", weight: 700 }]
: undefined,
}
)
}
async function loadFont(family: string) {
const css = await fetch(
`https://fonts.googleapis.com/css2?family=${encodeURIComponent(family)}:wght@700&display=swap`,
{
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko",
},
}
).then((res) => res.text())
const match = css.match(/url\((https:\/\/fonts\.gstatic\.com\/[^)]+)\)/)
if (!match) return null
return fetch(match[1]).then((res) => res.arrayBuffer())
}
How it works
- 01
Pick a template
Choose a visual starting point. Blog, product, minimal, gradient, code, and profile each ship with their own type and color.
- 02
Tune the card
Set the title, subtitle, author, font, and colors. A logo URL is optional and has to be a public https image.
- 03
Download or copy
Download the 1200×630 PNG, copy the image URL, or copy the Next.js file and meta tags for the template you picked.
What an OG image is
An Open Graph image is the picture a messaging app or social network shows when someone shares a link. The page points at it with an og:image tag, and the platform downloads that URL. A deliberate 1200×630 card keeps the title readable in the preview instead of leaving the network to grab a random screenshot.
Sizes by platform
| Platform | Size | Notes |
|---|---|---|
| Facebook / Open Graph | 1200 × 630 | 1.91:1. This is the size the generator exports. |
| 1200 × 627 | A 1200 × 630 image is accepted for link previews. | |
| X | 1200 × 675 | summary_large_image. 1200 × 630 still displays. |
| Slack | 1200 × 630 | Unfurls read og:image. |
| Discord | 1200 × 630 | Embeds use the Open Graph image. |
| 1200 × 630 | Large previews prefer this ratio. |
How to test a preview
- Copy the image URL, or put the generated
opengraph-image.tsxin your Next.js app. - Point
og:imageat an absolute https URL. A file namedopengraph-image.tsxdoes that for you. - Paste the page into the Facebook Sharing Debugger and scrape it again.
- Check the LinkedIn Post Inspector the same way.
- Drop the page URL into Slack or Discord and confirm the unfurl.
- If a platform still shows the old card, run its debugger refresh. Those caches ignore a normal reload.
FAQ
What size does this generator export?
Every image is 1200 by 630 pixels. That is the Open Graph size Facebook, LinkedIn, Slack, Discord, and WhatsApp expect for a large link preview.
Is the OG image generator free?
Yes. It is free to use in the browser. There is no account and no watermark on the PNG.
Are the images I generate stored?
No. The PNG is rendered when the image URL is requested and is not saved as a file. Browsers and the CDN may cache that exact URL for a day so the same card loads quickly the next time.
Can I use my own logo or avatar?
Yes. Paste an https URL to a PNG, JPEG, WebP, or GIF under 1.5 MB and 4096 pixels on each side. The server downloads it with a four second timeout and refuses local, private, and link-local addresses.
How do I use this in a Next.js app?
Open Get the code and copy the opengraph-image.tsx file into the App Router segment that should own the preview. Next.js serves that file as the page's og:image. You can also copy the image URL and set it as the absolute og:image on any other stack.
How do I check that a platform picked up the image?
Deploy the page, then paste its URL into the Facebook Sharing Debugger and the LinkedIn Post Inspector and run their scrape action. Also drop the URL in Slack or Discord. Those products cache previews, so the debugger refresh is what shows a card you just changed.