Use case · social previews · 1200 × 630

AI Open Graph images: generate the art, render the text

Generate a text-free background once per section, then let your framework draw the title over it at exactly 1200×630. That split is the whole technique. It gives every page a distinctive card without regenerating artwork every time a headline changes.

Every time a URL is shared in a chat, a channel or a feed, something renders. With an og:image it is a picture with your name on it. Without one it is a grey rectangle and a truncated title — and that is the only impression most people ever get of the page.

By the imagemcpserver.com teamPublished Updated
no og:image

Your page title, cut off at abou…

example.com

title composited at build time

Your page title, fully rendered

example.com

Generate the background. Render the words.

This split is what separates Open Graph images that scale to a whole site from ones that get regenerated every time a title changes. It also neatly sidesteps the fact that this API cannot produce a 1200×630 file itself.

generated once, per section · 15 cr

The background

A 16:9 image with no text in it, deliberately calm on the side where type will land. One per section of your site is usually enough — docs, blog, product, pricing. Pass an approved image in referenceImages so every section shares a visual language.

“Abstract paper-craft composition in cream and warm yellow, calm empty space in the left third, no text, no letters, soft studio shadow”

rendered per page, at build · free

The text layer

Title, section label and logo, drawn over the background by your framework’s image route. Crisp type, correct every time, and free to change — because changing it does not mean regenerating art.

The route owns the canvas, so it is also where the geometry is settled: a 16:9 backdrop is cover-fitted into the 1200×630 frame rather than padded by hand.

This site’s own card is built exactly this way

The backdrop behind our Open Graph card was generated with this API, saved into the repo, and is inlined as a data URI by the image route below — with a gradient scrim so the headline stays readable over it. Two details in there are worth stealing.

the image route
export const size = { width: 1200, height: 630 };
export const contentType = 'image/png';

export default async function OpenGraphImage() {
  // Read the generated backdrop off disk and inline it, so the
  // card never depends on a network fetch while rendering.
  const bg = await readFile(join(process.cwd(), 'public/og-bg.jpg'));
  const bgSrc = `data:image/jpeg;base64,${bg.toString('base64')}`;

  return new ImageResponse(
    <div style={{ width: '100%', height: '100%', display: 'flex' }}>
      <img src={bgSrc} width={1200} height={686}
           style={{ position: 'absolute', objectFit: 'cover' }} />

      {/* Scrim keeps the headline readable over busy artwork */}
      <div style={{ position: 'absolute', width: 1200, height: 630,
        background: 'linear-gradient(90deg, #FDF7E9 0%, ' +
                    '#FDF7E9 44%, rgba(253,247,233,0) 76%)' }} />

      {/* …title, section label and logo… */}
    </div>,
    { ...size }
  );
}

Sizes and limits

1200×630 is the number to design to, but it is a recommendation rather than a promise — X’s documentation suggests 2:1 for large cards and LinkedIn may crop taller images. Treat 1.91:1 as the ratio that degrades most gracefully everywhere, not one nothing ever touches.

Open Graph image dimensions and file-size limits, and the closest ratio this API generates.
WhatValueWhy it matters
Target size1200 × 630The 1.91:1 recommendation Meta documents for high-resolution displays.
Protocol minimum200 × 200Below this the Open Graph protocol does not guarantee a render at all.
File size ceiling8 MBMeta’s documented hard limit. Aim well under 1 MB in practice.
Closest ratio here16:9What this API generates. The renderer cover-fits it into the 1200×630 canvas.

Platform figures checked September 2026 against Meta’s sharing documentation and the Open Graph protocol. Both move — re-check before you hard-code them into a build step.

The checklist that stops previews breaking

1

Use an absolute URL

og:image must be a full https URL. A relative path silently fails on every platform that scrapes it.

2

Render at exactly 1200 × 630

Let the framework image route own the canvas size. Off-ratio files get cropped in ways you did not choose.

3

Inline the background, do not fetch it

An OG route that fetches a remote image can fail at render time. Read the file and embed it as a data URI so the card never depends on the network.

4

Put a scrim under the type

Generated artwork is busy. A gradient behind the headline keeps it legible no matter what the model drew.

5

Set og:image:width and height

It lets platforms lay out the card before the image loads, avoiding a flash of grey.

6

Add twitter:card = summary_large_image

Without it you get the small square card instead of the wide one.

7

Re-scrape after a change

Caches are aggressive. Use the platform’s debug tool, or version the filename.

Make it impossible to forget

Pages ship without an Open Graph image not because anyone disagreed that they should have one, but because the step lives outside the build. Move it inside and the problem stops recurring.

  • A build check that fails when a route has no og:image.
  • A generation call for any section background that does not exist yet.
  • A compression pass so nothing heavy ever reaches the CDN.
build-time backfill
const missing = sections.filter(
  (s) => !existsSync(`public/og/${s.slug}.webp`)
);

const requests = missing.map((s) => ({
  tool: "generate_image",
  args: {
    prompt: `${HOUSE_STYLE}, ${s.motif},
             no text, calm left third`,
    aspectRatio: "16:9",
    referenceImages: [BRAND_REFERENCE],
  },
}));

// One multicall, every missing background.
// Batches have no size cap, so keep them in the tens.

What it costs

Only the artwork costs credits. The text layer is rendered by your framework at build time, so per-page cards are free once the section background exists.

Credit cost of one Open Graph section background, and of a six-section set.
StepCallCredits
Section background, standard model1 × generate_image15
Compression pass1 × compress_image1
Text layer, every pageframework render0
One background · a 6-section site16 · 96

A whole site’s worth of social previews for 96 credits, then nothing per page after that. See plans →

Open Graph questions

What is the ideal image size for Open Graph?

1200×630 pixels, a 1.91:1 ratio, is the size to target — Meta's own sharing documentation asks for images at least that large for high-resolution displays, and the Open Graph protocol's floor is 200×200. It is a recommendation rather than a universal guarantee: X's documentation suggests 2:1 for large cards, and LinkedIn may crop taller images, so 1200×630 is the size that degrades most gracefully everywhere rather than the size nothing ever touches. Checked September 2026.

How do I make an Open Graph image?

Split it in two. Generate a text-free background once per section of your site, then let your framework render the title, label and logo over it at exactly 1200×630 at build time. The generated art gives you something distinctive; the rendered layer gives you crisp type that updates when the title does, without regenerating any artwork.

How big can the file be?

Meta documents a hard ceiling of 8 MB, but that is a limit rather than a target. Well under 1 MB is the practical aim: scrapers fetch these on a timeout, and a lighter file is scraped more reliably and rendered faster. A compression pass costs 1 credit and takes a generated background comfortably inside that. Checked September 2026.

Can this API produce the exact 1200×630 file?

Not on its own, and you do not want it to. The closest ratio it generates is 16:9, and no endpoint here resizes, pads or crops — there is no width or height parameter anywhere. That is fine, because the framework renderer that draws your text already outputs at exactly 1200×630 and cover-fits the background into that canvas. Generate the art, let the renderer do the geometry.

Should the page title be inside the image?

Yes, but not drawn by the image model. Generate a text-free background and composite the title over it programmatically. Baked-in type cannot be localised or corrected, and every title edit would mean regenerating the art. Rendered type is crisp, always matches the page, and is free to change.

Do I need a different image per page?

You need one that is not obviously generic. A single site-wide image beats none by a wide margin; one per section is better; per-page is worth it for the things people actually share — articles, docs pages, product pages. Since only the artwork costs credits and the text layer is rendered per page for nothing, per-section art with per-page titles is the sweet spot.

Why does my preview not update after I change the image?

Platforms cache scraped previews aggressively. Most publish a debugging tool that forces a re-scrape, and changing the filename or adding a version query string is the reliable way to break the cache when the tool is not enough.

Does an Open Graph image affect SEO?

Not as a direct ranking factor. It affects click-through from social apps and chat, which affects traffic — a link that renders as a grey box gets clicked and reshared less than one that renders as a picture. Treat it as distribution, not as ranking.

Reference