ogmake

OG images in Ghost

A Ghost theme is Handlebars templates only — there's no request-time code you can run to compute an HMAC signature (especially on Ghost(Pro), where the platform, not you, runs the Node process), so the signed GET /i/{keyId}/{sig} route (Signing) isn't usable from a theme. Use a public key instead — it only needs the same {{helper}} calls you'd use for any other dynamic value in default.hbs.

1. Create a public key

Sign in at /login, open the dashboard, check which templates the key may render (e.g. blog), then "Create public key". The key id (starts with k_) is safe to commit into your theme's source.

Still on a hand-issued beta key? Email support@ogmake.com.

2. Add it to the default template

In default.hbs's <head>, inside a {{#post}} context:

{{#post}}
<meta property="og:image" content="https://ogmake.com/p/k_yourkeyid/blog?site=example.com/blog&author={{encode primary_author.name}}&date={{encode (date published_at format="MMM D, YYYY")}}&title={{encode title}}" />
{{/post}}

Gotcha: Ghost's {{encode}} escapes one value, not a whole query string

Ghost's built-in {{encode}} helper URL-encodes a single output, which is exactly right for one field at a time (title, primary_author.name) — but it doesn't build or escape a full query string, so each param still has to be assembled by hand as shown above; there's no single helper that takes an object and returns a=1&b=2. Ghost also renders its own default og:image tag through {{ghost_head}} (built from the post's feature image, or the Admin "Meta Data" image if set), so a theme that includes {{ghost_head}} will still emit a second, competing og:image tag regardless of where your own tag sits in <head>. For posts that should use the generated image, clear the featured image and the Meta Data image for that post in Ghost Admin so {{ghost_head}} has nothing to render, and keep your own tag anywhere in <head>.

Verify it

View source on the published post (curl -s https://yoursite.com/some-post/ | grep 'og:image') and confirm only one og:image tag is present — two tags (yours plus Ghost's own) is the most common failure mode here. A bad or missing field on the public route is still a 200 fallback image rather than a visible error, so curl -I the image URL itself and check for x-ogmake-error (see debugging a public URL). Then run the live post through Facebook's Sharing Debugger, or compose a new post on X with the URL and check the card renders there (X retired its public Card Validator in 2022). Ghost's own CDN and social crawlers both cache by URL, so if you only change theme markup (not post content) and need a fresh preview, add a v query param tied to your theme's version.