GUIDE

How to Auto-Generate an og:image for Every Page You Publish

Manually exporting a preview image for every new page doesn't scale past a handful of URLs. Here's how to auto-generate an og:image for every page you publish instead.

August 16, 20267 min read

The first og:image most sites ship is hand-made: someone opens a design tool, exports a 1200×630px PNG, and uploads it alongside a new blog post or landing page. That works fine for a site with five pages. It breaks down completely once you're publishing daily, running a blog with a real posting cadence, or generating pages faster than a person can open a design file — which is most sites within a year of launch. The fix isn't a faster designer. It's a way to auto-generate an og:image for every page at publish time, without a human touching an export button.

Why manual export stops working

The failure mode isn't dramatic — it's just quiet neglect. A new page ships without an og:image because whoever wrote the copy isn't the person who normally exports images, or because it's a Friday and the export step gets skipped 'for now.' Weeks later, someone notices the page has no preview when shared, or worse, it inherited a stale default image from a template that no longer matches the content. Neither failure shows up in a build error. It just sits there, silently making every share of that page look unfinished.

There's also a consistency problem that has nothing to do with anyone forgetting. Even when the export happens every time, five different contributors manually cropping and placing text produce five different-looking cards — different font sizes, different logo placement, different amounts of padding around the headline. None of it is wrong exactly, but it reads as unplanned when you look at the set of pages together, and it means every new page is redoing layout decisions that should have been made once.

What auto-generation actually replaces

Auto-generating an og:image means the image is produced programmatically from a template and the page's own data — its title, a category label, maybe a featured image — rather than assembled by hand in a design tool each time. The template defines the layout once: where the headline sits, how large the type renders, where the logo goes, what the background looks like. Publishing a new page doesn't require a design step at all; it just needs the page's title and description to exist, because those already flow into the template as variables.

This is a genuinely different workflow, not just a faster version of the manual one. In the manual flow, the image is a separate asset someone creates and attaches to a page. In the automated flow, the image is a rendered output of the page's own metadata — it can't drift out of sync with the title because it's generated from the title. If a blog post title changes after publish, regenerating from the same template with the updated variable is a non-event instead of a follow-up task someone has to remember.

Setting up templates that generalize

The work that does need doing up front is designing a template (or a small set of templates) that looks right across a wide range of content — a three-word title and a twenty-word title, a page with a featured photo and one without. That means picking a font size that doesn't overflow on long titles, deciding what happens when there's no image to drop into an image slot, and setting safe margins so nothing critical sits near an edge that different platforms crop differently.

  • Design for the longest realistic title, not the shortest — test with a full sentence, not a placeholder word
  • Define a fallback for any variable that might be empty (no author photo, no category tag) so the template never renders a broken layout
  • Keep the template to a handful of variables (title, category, image) rather than trying to make every field customizable per page
  • Preview the rendered output on a handful of real pages before rolling it out sitewide, not just the design mockup

Different content types, different templates

One template rarely covers an entire site well. A blog post benefits from a layout built around a headline and maybe an author name. A product page benefits from a layout built around a product photo and a price. A pricing or landing page often works best as a simpler brand card with no dynamic text at all. Auto-generation doesn't mean one image for the whole site — it means each content type has its own template, and every page of that type inherits it automatically instead of being designed individually.

The variables you feed into a given template are also worth being deliberate about. Pulling directly from the page's H1 and meta description keeps the OG image honest to what the page is actually about, which matters both for user trust and because a mismatched preview (an image describing something other than the linked page) tends to read as spammy or broken when someone clicks through expecting one thing and finding another.

Where publishing pipelines break this in practice

Even with a template in place, auto-generation can fail quietly if it's not actually wired into the publish flow. A common gap: the template exists and works, but new pages still need someone to manually generate and attach the render URL, which reintroduces the exact manual step the template was supposed to eliminate. The stronger setup ties image generation to the publish action itself, or to the page build, so a new URL is live with a correct og:image the moment the page exists — no separate export, no separate upload, no step to forget.

Handling edge cases in the pipeline

Once auto-generation is wired into publishing, a few edge cases need explicit handling rather than being left to fail silently. A page created without a title yet (a draft saved before anyone's written the headline) shouldn't trigger a broken render — the pipeline needs a sensible placeholder or should simply wait until the required fields exist. A page updated after initial publish (a title edit, a swapped hero photo) should regenerate its image rather than leaving the old render attached to new content, since a stale image is arguably worse than no image at all — it actively misrepresents what the page now says. And a page deleted or unpublished should ideally stop being referenced anywhere a card might still surface it, though this matters less in practice since most platforms re-fetch metadata per share rather than caching indefinitely.

Rate and volume also matter more than they first appear to. A site publishing one page a week can get away with generation that takes a few seconds per page, run synchronously as part of publish. A site importing a catalog of ten thousand products in one batch needs generation that can run asynchronously and at scale without blocking the import itself, and needs a clear way to tell which pages succeeded and which need a retry. Neither problem is unusual, but both are the kind of thing that only becomes visible once volume actually arrives, which is why it's worth thinking through before the first large batch rather than after it fails partway.

Measuring whether auto-generation is actually working

The easiest way to confirm auto-generation is functioning as intended isn't to trust that the pipeline ran — it's to periodically spot-check a sample of recently published pages against what's actually live. A page that published successfully but whose og:image tag still points at a placeholder, a broken URL, or an old template version is a silent failure that a build succeeding doesn't rule out. Treating this as a recurring check rather than a one-time setup verification catches the cases where a template gets renamed, a CMS field mapping breaks after an unrelated change, or a batch import partially fails without raising an obvious error.

How useopengraph handles this

useopengraph generates OG images from templates with variables for text, image, and color, and every render is served from a versioned URL under /api/render/{templateId}/v{version}/... Publishing a template creates a new version; existing rendered URLs never change underneath you, so pages that already went live keep the exact image they shipped with, even after you tweak the template for future pages. In practice this means you set up a template once per content type — blog post, product page, landing page — feed it that page's title and data as variables, and every new URL gets a correctly sized, on-brand og:image automatically, with no export step and no design tool in the loop for page number two thousand any more than page number two.

Stop paying per seat
for a usage-shaped problem.

Unlimited teammates, one usage pool. Start free with the scanner — no card required.