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.