Skip to main content
Free3 minutesBeginner

Ghost Integration

Add Zenovay analytics to your Ghost publication through Settings → Code Injection → Site Header. Works on every Ghost plan including self-hosted.

ghostcmsblogintegrationtracking-script
Last updated:

Add Zenovay to any Ghost publication in two minutes. Code Injection is available on every Ghost plan, including self-hosted Ghost CMS — no upgrade required.

Code Injection is available on all Ghost plans, including self-hosted Ghost CMS. Custom themes need the {{ghost_head}} helper in default.hbs (most themes already have it).

Quick Start

  1. Copy your tracking snippet from the Zenovay dashboard.
  2. In your Ghost admin, open Settings → Code injection → Site Header.
  3. Paste the snippet.
  4. Click Save.

Installation

  1. Log in to your Ghost admin (usually https://your-site.com/ghost/).
  2. Click Settings (gear icon).
  3. Scroll to Site → Code injection.
  4. Paste this snippet into the Site Header box:
<script defer data-tracking-code="YOUR_TRACKING_CODE" src="https://api.zenovay.com/z.js"></script>
  1. Click Save.

Per-post / per-page injection

For tracking only a specific post:

  1. Open the post in the editor.
  2. Click the gear icon (settings) in the top-right.
  3. Expand Code injection.
  4. Paste the snippet into Post Header.
  5. Update the post.

Don't paste in both site-wide and per-post — you'll double-count.

Verify your installation

  1. Open your Ghost site in an incognito window.
  2. View source and look for <script defer data-tracking-code=...> in the <head>.
  3. Check the Zenovay real-time view — your visit appears within ~30 seconds.

Identify Ghost members

Ghost exposes the current member through /members/api/member/. Identify on every page:

<script>
  fetch('/members/api/member/', { credentials: 'include' })
    .then(r => r.ok ? r.json() : null)
    .then(member => {
      if (member && window.zenovay) {
        window.zenovay('identify', {
          userId: member.uuid,
          email: member.email,
          name: member.name,
          plan: member.subscriptions?.[0]?.plan?.nickname,
        });
      }
    })
    .catch(() => {});
</script>

Tracking newsletter signups

Ghost signup forms emit a standard submit event:

<script>
  document.addEventListener('DOMContentLoaded', () => {
    document.addEventListener('submit', (e) => {
      const form = e.target;
      if (form?.matches('[data-members-form]')) {
        window.zenovay?.('track', 'signup', {
          form_type: form.dataset.membersForm || 'signup',
        });
      }
    }, true);
  });
</script>

Tracking paid subscription clicks

Ghost renders portal-trigger buttons with data-portal attributes:

<script>
  document.addEventListener('click', (e) => {
    const target = e.target.closest('[data-portal]');
    if (target && window.zenovay) {
      window.zenovay('track', 'portal_opened', {
        action: target.dataset.portal,
      });
    }
  }, true);
</script>

For accurate revenue attribution on paid memberships, use Ghost's Stripe webhook integration and send Stripe events to Zenovay via server-side tracking.

Working with custom Ghost themes

Code Injection renders through the {{ghost_head}} Handlebars helper. If you use a custom theme, make sure default.hbs contains:

{{ghost_head}}

…inside the <head>, before </head>. Most third-party Ghost themes (Casper, Source, Edition, etc.) include this by default.

Troubleshooting

No data, custom theme. Check that {{ghost_head}} is present in your default.hbs. Without it, Code Injection has nowhere to render.

No data on /amp/ URLs. If you've enabled the Ghost AMP integration, Code Injection doesn't apply to AMP variants (AMP strips arbitrary scripts). Either disable AMP or accept that AMP traffic isn't tracked.

Double pageviews. Snippet pasted in both Site Header and per-post Code Injection. Pick one scope.

Members never identified. /members/api/member/ returns 404 on older Ghost versions (< 4.x). Upgrade your Ghost installation.

Plan requirements

Ghost editionCode InjectionCustom themes
Ghost(Pro) Starter❌ (Casper only)
Ghost(Pro) Creator
Ghost(Pro) Team / Business
Self-hosted Ghost CMS

Privacy

For cookieless tracking add data-cookieless="true":

<script defer
        data-tracking-code="YOUR_TRACKING_CODE"
        data-cookieless="true"
        src="https://api.zenovay.com/z.js"></script>

Ghost's own member analytics use first-party cookies anyway, so layering Zenovay in cookieless mode is a common pattern.

Next steps

Was this article helpful?