Joshua Aragon Eab4ml7c7fe Unsplash.jpg

Everything About Subscription Forms in Ghost

Subscription forms are essential for your Ghost theme, as they allow you to grow a member list and interact with your users. Ghost enables this functionality as long as your theme cooperates by providing the necessary configuration.

Most themes you start with handle everything for you, but what if you want to make changes?  Or start a new Ghost theme from scratch?  This article will teach you how it all works and how you can use it in your themes.

Why your Ghost Theme Needs Subscriptions Forms

At a minimum, Ghost subscription forms allow you to collect the email addresses of people who come to your site.  The collected addresses show up in the members’ list of the Ghost admin panel after the user confirms their address using a link sent via email.

Subscription forms can be used in many ways:

  • Sidebar
  • Call to Action (CTAs)
  • Exit intent popups

Each of these uses looks slightly different but uses the same core mechanism. Here’s an example:

Subscription form in Ghost

How Do You Add a Subscription Form to a Ghost Theme?

Subscription forms are just normal HTML forms with extra data attributes instructing Ghost how to handle the data.  One input field is designated to contain the email address of the user, which is sent to Ghost when the user submits the form.

Here is a subscription form from the default Ghost theme, Casper:

<form data-members-form="subscribe">    <div class="form-group">        <input class="subscribe-email" data-members-email placeholder="[email protected]" autocomplete="false" />        <button class="button primary" type="submit">            <span class="button-content">Subscribe</span>            <span class="button-loader">{{> "icons/loader"}}</span>        </button>    </div>    <div class="message-success">        <strong>Great!</strong> Check your inbox and click the link to confirm your subscription.    </div>    <div class="message-error">        Please enter a valid email address!    </div></form>

This form is wrapped with extra HTML, like a title for the form, but the above is all you need to make it work.

WARNING: Remember to conditionally include subscribe forms using {{#if @labs.members}} in handlebars.  This allows users to enable Ghost membership using the admin ‘General’ page (although it’s rare to turn this off).

The form is enabled by adding the attribute data-members-form="subscribe" to the form tag in line 1.  The single input is designated to contain the user email by the data-members-email attribute in line 3.  Finally, a normal submit button submits the form.

Note that the form contains no action or method – it doesn’t need to.  Ghost handles all this automatically via JavaScript code (see below for how).

There are two final div tags in the form with classes message-success and message-error.

These are not controlled by the form itself, nor are they required.  These divs are conditionally shown or hidden by CSS based on the form state.  In other words, if you use this method in your theme, then you have to include CSS for the message-success and message-error classes.

How Does the Subscription Form Work?

Ghost automatically inserts a JavaScript file named portal into a theme using the ghost_head helper.

Before 3.34 this file was named members.  The JavaScript searches the html on page load for any forms that have the data-members-form attribute set to ‘subscribe’ and binds the submit button in that form.

When a user clicks subscribe, the form sends a POST request to the API (specifically the send-magic-link API endpoint) containing the value of the input with the data-members-email attribute.

During the submission process, the <form> tag is assigned classes to indicate state:

  • loading: This class is added while the POST request is pending and is used to show a busy indicator.
  • success: Added when the form was submitted successfully and generally used to show the div with the message-success element.
  • error: Form submission resulted in an error.  One such error is that email isn’t configured properly, which is frequently the case for local/dev Ghost instances.  The error classes usually display a generic error message by showing the message-error div.
  • invalid: This class is still styled in some themes, but doesn’t seem to be used anymore.  The invalid class used to indicate that the email was incorrectly formatted but now bad emails just show the error class.

The user must then confirm the email address they submitted within 10 minutes.

Email Confirmation

After a user signs up, they are sent an email containing a confirmation link. Clicking the link instructs Ghost to change the member from ‘pending’ to ‘subscribed’ and then redirects them back to the original website.

The redirect contains two query string parameters ‘action’ and ‘success’: action is set to ‘subscribe’ and success is ‘true’ or ‘false’ (omission of the success parameter defaults to ‘true’).  For example:


It’s entirely up to the theme to notify the user when the subscription was successful.

The standard mechanism is to use JavaScript to add classes to the body tag, which in turn shows a message to the user.  This is the mechanism that both the Mindspun and Casper default themes use.

Full-screen Subscribe CTA

Another mechanism for presenting a user with a subscribe form is a call-to-action button, usually in the header.

Clicking this Ghost subscribe button shows a full-screen overlay with the subscription form.  The full-screen subscription form uses the exact same mechanism as the inline form, only shown in an div element that covers the entire viewport.

The overlay is conditionally shown based on a ‘subscribe’ anchor tag in the URL.   For example:


The presence of the anchor tag shows a div in the theme with the id ‘subscribe’ and the class ‘subscribe-overlay’.   This is done by a clever CSS rule like:

.subscribe-overlay {    opacity: 0;}subscribe-overlay:target {    opacity: 1;}

The first rule hides the overlay by default.  The second rule shows the overlay only when the anchor in the URL matches the id of the div (the :target selector).  This means the /#subscribe URL would show a div like:

<div id="subscribe" class="subscribe-overlay ...">    ...</div>

The contents of this div would be the standard subscription form like at the beginning of this article.

Easily Integrate Subscription Forms into Your Theme

The easiest way to enable a subscription form in your Ghost theme is to use the ghost-theme-utils NPM package.  This package contains all the styling you need in both CSS and SCSS formats plus the necessary JavaScript.  You can add these files via the CDN:


<link href="https://cdn.jsdelivr.net/npm/ghost-theme-utils@latest/dist/css/style.min.css" rel="stylesheet">


<script src="https://cdn.jsdelivr.net/npm/ghost-theme-utils@latest/dist/js/ghost-theme-utils.min.js" async defer></script>

You can see a live version of this library – with simulated Ghost functionality – here.  This demo site isolates the functionality to more clearly show what going on without everything else in the theme being present.


This article describes how the Ghost subscriptions work and explains how to easily integrate them into your theme.

This functionality is crucial to any site and while included in most themes, it’s not well documented anywhere else, leaving the theme developer to hope they implemented everything.

By following this article, you’ll fully understand the functionality. Best of all, you can just let the ghost-theme-utils package does the heavy lifting for you.

Subscribe for Email Updates

Everything an ambitious digital creator needs to know.