Skip to content

synapsmedia/ghost-image-generator

Repository files navigation

Ghost Image Generator

HTML-based Open Graph image generator with first-class Ghost CMS support.

The service renders Handlebars templates to PNG images using Express and Puppeteer. It can be used as a generic HTML image generator, and it also includes Ghost-specific endpoints that fetch post and site data from a Ghost publication.

Features

  • Generate PNG images from Handlebars templates
  • Render template previews as HTML
  • Configurable width, height, and device pixel ratio
  • Built-in Ghost CMS post image generation
  • Static CSS and public assets support
  • Production Docker image published to GitHub Container Registry
  • Local development with Docker Compose and nodemon

Quick Start

Run the published image:

docker compose up

The service will be available at http://localhost:3000.

Generate a basic image:

curl "http://localhost:3000/image/default?title=Hello%20World&description=Rendered%20from%20HTML" > image.png

Preview the rendered HTML:

curl "http://localhost:3000/template/default?title=Hello%20World"

Docker Image

Published image:

ghcr.io/synapsmedia/ghost-image-generator:latest

Run it directly:

docker run --rm -p 3000:3000 ghcr.io/synapsmedia/ghost-image-generator:latest

Build locally:

docker build -t ghost-image-generator .
docker run --rm -p 3000:3000 ghost-image-generator

Development

Start the development container:

docker compose -f docker-compose-dev.yml up --build

This mounts src/, templates/, styles/, and public/ into the container and runs npm run dev.

You can also run it without Docker if you have Node.js and a local browser setup:

npm install
npm run dev

API

Generate Image

GET /image/{templateName}?width&height&dpr&otherTemplateVariables

Parameters:

  • templateName: template file name without .hbs
  • width: viewport width in pixels, default 1200
  • height: viewport height in pixels, default 630
  • dpr: device pixel ratio, default 2
  • Additional query parameters are passed to the template

Example:

curl "http://localhost:3000/image/article?title=Hello%20World&description=A%20test%20image&author=Jane%20Doe" > article.png

Preview Template

GET /template/{templateName}?otherTemplateVariables

Example:

curl "http://localhost:3000/template/article?title=Hello%20World&description=A%20test%20image"

Generate Ghost Image

GET /image/{templateName}/ghost/{domain}/{postSlug}?contentApiKey&width&height&dpr

Parameters:

  • templateName: template file name without .hbs
  • domain: Ghost site domain, for example example.com
  • postSlug: Ghost post slug
  • contentApiKey: Ghost Content API key
  • width: viewport width in pixels, default 1200
  • height: viewport height in pixels, default 630
  • dpr: device pixel ratio, default 2

Example:

curl "http://localhost:3000/image/ghost-post/ghost/example.com/my-post?contentApiKey=your-api-key" > ghost-post.png

Preview Ghost Template

GET /template/{templateName}/ghost/{domain}/{postSlug}?contentApiKey

Example:

curl "http://localhost:3000/template/ghost-post/ghost/example.com/my-post?contentApiKey=your-api-key"

Health Check

GET /health

Response:

{"status":"ok"}

Templates

Templates live in templates/ as .hbs files. Matching stylesheets can live in styles/ and be referenced through /styles/{file}.css.

Included templates:

  • default: simple generic Open Graph image
  • article: article/blog post layout
  • minimal: clean black-and-white layout
  • ghost-post: Ghost post layout with publication branding
  • ghost-simple: centered Ghost post layout
  • ghost-feature: Ghost post layout using the feature image as the background

Generic templates receive query-string values directly:

<h1>{{title}}</h1>
<p>{{description}}</p>

Ghost templates receive site and post objects fetched from Ghost:

<h1>{{post.title}}</h1>
<p>{{site.title}}</p>

GitHub Actions

The Docker workflow in .github/workflows/docker.yml:

  • Builds the image on pull requests
  • Publishes to ghcr.io/synapsmedia/ghost-image-generator on pushes to main or master
  • Publishes version tags for Git tags matching v*.*.*
  • Publishes latest from the default branch

The workflow uses GITHUB_TOKEN and does not require extra registry secrets for GitHub Container Registry publishing.

Technical Details

  • Runtime: Node.js LTS Docker image
  • Web framework: Express
  • Template engine: Handlebars
  • Screenshot library: Puppeteer with system Chromium
  • Image format: PNG
  • Default dimensions: 1200x630
  • Default DPR: 2

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors