How Ghost's themes work under the hood

Ghost's theme system is a powerful and flexible framework that allows users to customize the appearance and functionality of their Ghost-powered websites. Under the hood, it combines templating engines, structured data flow, and modular design to enable deep customization. Below is a detailed breakdown of how it works:


1. Templating Engine: Handlebars.js

Ghost uses Handlebars.js as its core templating engine. Handlebars allows developers to create dynamic HTML templates by embedding placeholders (e.g., {{title}}) that are replaced with actual data at runtime. Key features include:

  • Template Files: Each page type (e.g., homepage, post, tag archive) corresponds to a .hbs file (e.g., index.hbs, post.hbs).
  • Context-Aware Rendering: Templates are rendered with specific data contexts. For example, post.hbs receives a post object with properties like title, content, and publish_date.
  • Helpers: Ghost extends Handlebars with custom helpers (e.g., {{#has tag="news"}} to conditionally render content) and output helpers (e.g., {{content}} to render sanitized HTML).

2. Theme Structure

A Ghost theme is a directory with a strict file/folder structure:

my-theme/
├── assets/            # CSS, JS, images (compiled/minified)
├── partials/          # Reusable components (e.g., header.hbs, footer.hbs)
├── templates/         # Main page templates (index.hbs, post.hbs, etc.)
├── default.hbs        # Base layout wrapping all templates
├── package.json       # Metadata (name, version, engines.ghost)
└── locales/           # Translation files for i18n (optional)
  • default.hbs: The root layout that wraps every page. Includes boilerplate HTML and injection points like {{{body}}} (where page content is inserted) and {{ghost_head}}/{{ghost_foot}} (for Ghost-generated scripts/styles).
  • Templates: Follow naming conventions (e.g., tag.hbs for tag archives). Custom templates can be assigned via the Ghost admin panel.
  • Partials: Reusable snippets included via {{> partial-name}}.

3. Data Flow & Content API

  • Data Sources: Ghost themes pull content from the Ghost Content API (v3 or v4). When a page is requested, the server fetches data (posts, authors, tags) from the database and injects it into the template context.
  • Template Contexts: Each template has access to specific data:
    • post.hbs: Receives a post object with title, excerpt, feature_image, etc.
    • author.hbs: Gets an author object and their associated posts.
    • Global data like @site (site title, URL) and @config (theme settings) is available everywhere.

4. Customization & Configuration

  • config.json: Defines theme settings (e.g., color pickers, dropdowns) editable via the Ghost admin. These settings are accessible in templates via @custom.property_name.
  • CSS Custom Properties: Themes often use CSS variables (e.g., var(--primary-color)) linked to config.json options, allowing dynamic styling without template edits.
  • i18n Support: Localization files in locales/ enable multilingual themes using {{t "key"}} helpers.

5. Asset Pipeline

  • Preprocessing: Ghost supports CSS preprocessors (Sass, Less) and JS bundling via build tools (Webpack, Gulp). Developers often use gscan (Ghost's theme validator) during development.
  • Asset Helpers: The {{asset}} helper generates URLs for compiled assets (e.g., {{asset "css/screen.css"}}).
  • Image Optimization: The {{img_url}} helper generates responsive images with srcset and optimizes them via Ghost's image service.

6. Routing & Template Hierarchy

Ghost maps URLs to templates using a predefined hierarchy:

  1. Custom Templates: Assign specific templates to posts/pages via the admin panel.
  2. Context-Specific Files: For example, tag.hbs handles /tag/:tag/ routes.
  3. Fallbacks: If no template matches, Ghost uses index.hbs as the default.

7. Hooks & Integrations

  • {{ghost_head}}/{{ghost_foot}}: Injection points for Ghost-generated code (SEO metadata, member scripts, or integration snippets).
  • Apps & Hooks: Themes can interact with third-party services via Ghost's Apps framework, which injects code at predefined hooks.

8. Development & Debugging

  • Ghost CLI: Developers use ghost install and ghost start to run a local instance. The ghost doctor tool checks for issues.
  • Theme Checks: gscan validates themes for compatibility and security.
  • Caching: Compiled templates are cached in production. Cache is disabled in development for real-time previews.

9. Security & Sanitization

  • Output Sanitization: Content rendered via {{content}} is sanitized to prevent XSS attacks.
  • Strict Sandboxing: Themes run in a restricted environment—they can’t execute server-side code or directly access the database.

10. Updates & Maintenance

  • Marketplace Updates: Themes installed via Ghost's marketplace receive version checks and one-click updates.
  • Backward Compatibility: Ghost ensures theme API stability across versions, isolating core changes to prevent breakage.

11. Headless Mode (Decoupled Frontends)

For headless setups, Ghost's Content API delivers JSON data, allowing themes to be rebuilt with frameworks like React or Vue.js while retaining Ghost's backend.


Under the Hood Workflow

  1. Request Handling: When a user visits a URL, Ghost determines the appropriate template and data context.
  2. Data Fetching: Content is retrieved from the database/API.
  3. Template Rendering: Handlebars compiles the template, merges it with data, and executes helpers.
  4. Asset Injection: CSS/JS assets and Ghost scripts are added via helpers.
  5. Response: Final HTML is sent to the client.

By combining these elements, Ghost themes offer a balance of flexibility, performance, and ease of use, empowering both developers and content creators.