Ghost Blog Featured Image Fallback Generated from Post Title
Generate a fallback image for Ghost blog posts when feature_image is null using the Ghost Content API and a title-based placeholder URL.
Ghost stores the featured image URL in a `feature_image` field on each post. The field is null for any post published without an image — which includes many newsletters, tutorials, and quick notes. Templates that render the field without a null check produce broken-image icons in post cards, headers, and Open Graph meta tags.
The Ghost Content API lets you handle this entirely at the data layer. When `feature_image` is null, substitute a fallback.pics URL built from the post title. The generated image appears immediately and looks like an intentional placeholder rather than a missing asset.
Ghost API
The feature_image field and when it is null
The Ghost Content API returns posts with a `feature_image` field that is either a string URL or `null`. There is no default image in Ghost's data model — the field is simply absent when no image has been set. Ghost's Handlebars helper `{{#if feature_image}}` handles this correctly in native themes, but headless frontends using the JSON API need their own null check.
Ghost also returns `feature_image_alt` and `feature_image_caption`. These are null whenever the image itself is null. Your fallback should either omit these fields or supply a safe default alt text derived from the post title.
Headless setup
Fetching posts with the Ghost Content API
The `@tryghost/content-api` npm package wraps the HTTP API. Each post object includes `feature_image` as a nullable string. Fetch posts with the fields you need and apply fallback logic after the fetch — not inside the component.
For static site builds (Astro, Next.js, Eleventy), compute fallback URLs during the build. For client-side Ghost-powered sites or ISR routes, compute them in the data-fetching layer before passing to components.
import GhostContentAPI from '@tryghost/content-api';
const api = new GhostContentAPI({
url: process.env.GHOST_URL,
key: process.env.GHOST_CONTENT_API_KEY,
version: 'v5.0',
});
function ghostPostImage(post: GhostPost): string {
if (post.feature_image) return post.feature_image;
const title = encodeURIComponent(post.title);
return `https://fallback.pics/api/v1/1200x630?text=${title}`;
}
export async function getPosts() {
const posts = await api.posts.browse({ limit: 'all' });
return posts.map((post) => ({
...post,
feature_image: ghostPostImage(post),
}));
} Thumbnail style
Use the thumbnail route for blog-card style fallbacks
The basic dimension route gives you a solid-color placeholder. The thumbnail route generates a blog-card layout with a title, category label, gradient, and safe-zone decoration. For Ghost blogs where every post should look publication-quality even before photography is ready, the thumbnail route is a better default.
Map Ghost's primary tag to the thumbnail `label` parameter. This gives each post card a category pill that matches the blog's taxonomy, making fallback images look intentional rather than generic.
function ghostThumbnailUrl(post: GhostPost): string {
if (post.feature_image) return post.feature_image;
const params = new URLSearchParams({
text: post.title,
label: post.primary_tag?.name ?? 'Blog',
style: 'soft',
theme: 'purple',
});
return `https://fallback.pics/api/v1/thumbnail/1200x630?${params}`;
} Handlebars themes
Fallback in native Ghost Handlebars themes
In a native Ghost Handlebars theme, the `{{feature_image}}` helper outputs nothing when the field is null. You cannot pass it a default value directly. Instead, use a custom helper or a conditional block to output the fallback URL.
Register a custom `featureImageOrFallback` helper in your theme's `helpers.js` file. This is cleaner than duplicating the conditional in every template partial.
{{! In your theme template (e.g. index.hbs, post.hbs) }}
{{#if feature_image}}
<img src="{{feature_image}}" alt="{{feature_image_alt}}" width="1200" height="630" />
{{else}}
<img
src="https://fallback.pics/api/v1/thumbnail/1200x630?text={{encode title}}&label={{primary_tag.name}}&style=soft&theme=purple"
alt="{{title}}"
width="1200"
height="630"
/>
{{/if}} RSS feed
Feature images in the Ghost RSS feed
Ghost's RSS feed includes `<media:content>` tags for featured images. When `feature_image` is null, the RSS item has no image, which means podcast apps, RSS readers, and feed aggregators show a blank entry. If your Ghost blog is also used as an RSS feed source, the fallback URL should be included in the feed output.
For headless Ghost setups, you control the RSS generation. Include the fallback URL in the feed item's image field. For native Ghost themes, a custom template in `ghost.hbs` or a route configuration is needed to inject fallback URLs into the feed.
Resources
Further reading
The fallback.pics thumbnail route documentation covers all style, theme, and label parameters. For full open graph image strategies, the OG image placeholders guide is a useful reference.
https://fallback.pics/docs/
https://fallback.pics/placeholder-image-api/
https://fallback.pics/blog/generate-blog-thumbnails-from-text/
https://fallback.pics/blog/hubspot-cms-image-fallback/ Key takeaways
What to standardize before shipping
- Ghost's feature_image field is null when no image is set — check before using as img src or og:image.
- Compute fallback URLs in the data-fetching layer, not inside components, so every template gets a valid string.
- Use the thumbnail route with the post title and primary tag label for publication-quality fallback cards.
- Apply the same fallback URL to Open Graph and Twitter Card meta tags to ensure social previews always render.
- In native Handlebars themes, use a {{#if feature_image}} block since the helper has no default value parameter.
Production fallback layer
Use fallback.pics anywhere an image URL is accepted.
Start with one deterministic URL and standardize fallback behavior across your design system.