Dynamic OG generation

CMS Dynamic OG Images: Wire Ghost & WordPress

By Social Card Studio5 min read

To make a CMS generate a dynamic OG image, point your og:image meta tag at an endpoint that takes the post's title, author, and template as URL parameters and returns a 1200×630 PNG. In Ghost you inject the tag through code injection or a theme template; in WordPress you filter the og:image output. Set the template once, and every post ships a branded social card automatically — no per-post export, no design tool.

What is a dynamic OG image, and why wire it to your CMS?

A dynamic OG image is a social card built at request time from a post's metadata, rather than a static file you design and upload by hand. The og:image tag points at a generator endpoint — https://card.example.com/og?title=...&template=... — and that endpoint reads the parameters, composes the card, and returns a 1200×630 PNG. Your CMS already holds the title, author, and publish date; wiring it to a dynamic endpoint means those fields flow straight into a branded card with zero manual steps.

The payoff is consistency at scale. Manual cards drift — one post gets a designed image, the next gets nothing and falls back to a blank gray box. A dynamic endpoint guarantees every post gets the same branded, correctly-sized card.

+114%
more impressions for posts and links that include an image versus none — which is exactly what a blank or missing card costs you. CXL, click-through benchmarks

Static uploads vs. dynamic generation: which fits your CMS?

Manual upload per postDynamic OG endpoint
Per-post effortDesign + export + upload each timeZero — built from metadata
Brand consistencyDrifts as authors skip itEnforced by the template
Correct 1200×630 sizeDepends on the authorGuaranteed by the renderer
Title always currentStale if the post is renamedRe-renders from live metadata
Best forA handful of cornerstone postsAny blog publishing regularly

Static uploads make sense for a few hand-tuned landing pages. For a blog that ships posts on a schedule, dynamic generation is the only approach that stays consistent without becoming a chore. If you want the underlying mechanics of the rendering layer, the dynamic OG image API guide covers how the endpoint itself works; this guide is about the CMS wiring.

How do you wire Ghost to a dynamic OG endpoint?

Ghost reads Open Graph tags from its theme and from any code you inject. The cleanest path is a theme template that outputs an og:image tag whose content is your endpoint URL with the post title encoded in:

{{!-- in default.hbs or post.hbs --}}
<meta property="og:image"
  content="https://card.example.com/og?title={{encode title}}&template=dispatch" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />

If you can't edit the theme, Ghost's Settings → Code injection site header is a fallback, though it can't read the per-post title the way a Handlebars template can — so prefer the theme route when you have it. Either way, the og:image value must be an absolute HTTPS URL; a relative path is the single most common reason a preview comes back blank.

How do you wire WordPress to a dynamic OG endpoint?

WordPress has no native Open Graph output, so the tag comes from either a plugin (Yoast, the OG plugin) or a theme filter. To inject a dynamic endpoint, filter the og:image value to your generator URL built from the current post title:

add_filter( 'wpseo_opengraph_image', function () {
    $title = rawurlencode( get_the_title() );
    return "https://card.example.com/og?title={$title}&template=verso";
} );

That hook targets Yoast specifically. If you run a different plugin, filter its equivalent output, or — on a custom theme — echo the og:image tag directly in wp_head. The principle is identical to Ghost: the title flows from post metadata into the endpoint URL, and the endpoint returns the card. For the full tag breakdown both CMSes depend on, see the Open Graph meta tag reference.

Why caching is non-negotiable for a CMS-wired endpoint

A dynamic endpoint renders on demand, which sounds expensive — but platforms scrape each URL once and store the result. The first time Facebook or Slack fetches your card, it renders; every share after that hits the platform's cache. The job on your side is to cache the rendered PNG keyed by title and template so even the first scrape of a re-shared post is cheap.

100–200 KB
is the target file size for a fast-loading card; a 1200×630 JPEG at quality ~80 lands around 150 KB, small enough that scrapers never time out. MyOG Image, 2025

Keep the parameter set small and stable. If your URL encodes a timestamp or a session value, every request is a cache miss and the card changes on every scrape — which can desync the preview a platform already stored. Title and template are enough.

+73%
more shares for headlines containing numbers — a reason to render the post's real title into the card rather than a generic brand image, since the headline is what earns the click. Swanky Agency, blog-title research

The one-line takeaway

Wire your CMS once: output an og:image tag that points at a dynamic endpoint and passes the post title, then cache the result by title and template. Every Ghost or WordPress post ships a branded 1200×630 card with no manual work. Doing exactly that — deriving your brand kit, then auto-generating a correct card for every post — is what Social Card Studio is built for. When a preview still won't render, work through Why Your Link Preview Is Broken.

Frequently asked questions

How do I generate a dynamic OG image from my CMS?

Point your og:image meta tag at a dynamic endpoint that takes the post's title, author, and template as URL parameters, then renders a 1200×630 PNG on demand. In Ghost you inject the tag through code injection or a theme template; in WordPress you filter the og:image output. The endpoint reads the parameters and returns a branded card.

Why use a dynamic OG image instead of uploading one per post?

A dynamic endpoint builds the card from post metadata at request time, so every post gets a branded, correctly-sized 1200×630 image without manual design work. You set the template once; the title, author, and colors fill in automatically for every post you publish.

Can a dynamic OG image work with caching?

Yes, and it should. Cache the rendered PNG keyed by the post's title and template so repeat scrapes hit the cache instead of re-rendering. Platforms like Facebook and Slack scrape the URL once and store it, so the first render cost is paid once per unique card.

← All posts