Setting up custom member subscription forms for Ghost.

This tutorial is for anyone setting up a "self hosted" Ghost instance, not Ghost Pro users.

Ghost is a fantastic open source blogging platform that combines simple design with a ton of flexibility. It's basically Wordpress without the bloatware and plugin hell and if you like to tinker with web development, it gets infinitely more fun to play with. They also have a membership feature that lets you create email newsletters (similar to Substack or Revue) which is what got me interested.

I recently set up a self-hosted instance of Ghost for this blog and wanted to set up an email newsletter subscription with a custom sign-up form. I initialize assumed I'd need to design a custom theme to do this, because the Ghost documentation on custom signup forms is in the theme documentation, but later realized I could have done it entirely in the post or page editor. Of course, if you want to do fancier things like control access levels, enable sign-in / sign-out or have custom member profile pages, you'll want to start messing with the theme files, but if you're just looking for a basic subscription form to capture emails, there's a simpler way to do it.

There's a few gotchas along the way that I had to do some digging to figure out so this post compiles everything you need to do to get a simple custom subscription form working for your blog.

Disclaimer: Ghost has a new feature called "Portal" that lets you add a popup subscription form to any theme, but I wanted to customize the design a little more and decided to create my own form.

What you'll be able to build:

A custom email form like this. (This is my live working signup form)

Sending email...
Great! Check your inbox and click the link to confirm your subscription.
Please enter a valid email address!

When a user signs up, they will get an email asking them to confirm their subscription. When they click the confirm link, the will get added to the members list in your blog.  You can then start sending them emails.

Getting Started

There are 3 parts to it:

  1. Creating the sign up form
  2. Enabling the members feature
  3. 2 email configuration steps (transactional email + newsletter email)

1. Creating the sign-up form

From the Ghost member documentation, the simplest sign up form looks like this. There are two required elements for an email signup form — an email input field and a submit button. Use the data-members-form attribute for the form element and data-members-email for the email input field to create a standard email collection signup form.

Setting data-members-form="subscribe" tells Ghost to send a subscription confirmation email when someone submits the form.

<form data-members-form="subscribe">
  <input data-members-email type="email" required="true"/>
  <button type="submit">Continue</button>
Note - I'm not showing any CSS styling for the form elements. That's up to you.

To add this you can simply add an HTML block in on any post or page (e.g a subscription page) and add this in.

Next, Ghost changes the state of the form element based on the status of the form submission. The states are: "loading", "success", and "error", and you can handle those states with 3 message elements and simple CSS that conditionally hides or shows messages based on the form's state.

First append the status messages to the end of your form like this.

<form data-members-form="subscribe">
  <input data-members-email type="email" required="true"/>
  <button type="submit">Continue</button>

<div class="message-loading">
	Sending confirmation email...

<div class="message-success">
	Great! Check your inbox and click the link to confirm your subscription.

<div class="message-error">
	Please enter a valid email address!

Then, in the < > Code Injection section, in the Ghost admin, add this in the Site Header.

    form[data-members-form] .message-loading,
    form[data-members-form] .message-success,
    form[data-members-form] .message-error {
        display: none;

    form[data-members-form].loading .message-loading,
    form[data-members-form].success .message-success,
    form[data-members-form].error .message-error {
        display: block;

This CSS will basically hide the div elements with status messages unless the state of the form (managed by Ghost) matches the div class.

2. Enabling the members feature

In Ghost Admin, under "Labs", go into the Members section and toggle "Enable Members".

The new Portal feature might turn on automatically so since we're building a custom form, we'll enter Portal Settings and turn off "Show Portal Button".

Also turn on "Allow free member signup".

3. Email Configuration

Now open "Email Newsletter Settings" and you'll see this.

Ghost uses Mailgun (which is a paid transactional email service) for automated emails like subscription confirmation as well as the email newsletter. They do have a free tier for sending less than 1000 emails per month and they have reasonably good pricing but you will need to pay for it.

Are there other options than paying for Mailgun?
You can use other email newsletter platforms like MailChimp or ConvertKit if you find their pricing more favorable, and you can embed their signup forms on your pages in the same way. However, you'll need to manually send each post out through your third-party email service provider. If you want to separate your newsletter content from your blog content this isn't a big deal, but I wanted to automatically email every post I write to my subscribers.

Setting up Mailgun

If you've decided to go with Mailgun, follow these steps. Remember that there are two things we're going to get Mailgun to do.

  1. Send your actual email newsletter
  2. Send transaction email like subscription confirmation messages - Ghost can use nodemailer to send these emails out if you don't configure Mailgun to do it, but I recommend setting up Mailgun because nodemailer is less reliable and you'll need to manually install nodemailer if your server doesn't already have it.

Create Mailgun account and add new domain

  1. Create a Mailgun account and login.
  2. Under the Domains section click Add New Domain. (Hint: copy the password, you will need it later)
  3. Enter the domain from where you want to send the emails. Mailgun will recommend setting up a subdomain like to send emails from.
  4. Update your DNS records according Mailgun setup instructions. This step adds the SPF and DKIM records that authenticate Mailgun to send email for you.

Add Mailgun credentials in Ghost Admin

  1. Go to the Members section and expand Email Newsletter Settings.
  2. Fill Mailgun region and Mailgun domain, from your Mailgun account.
  3. Fill Mailgun API Key. You'll find the API key in your Settings > API Keys panel in Mailgun. Pick the "Private key" and paste it in Ghost.
Mailgun Settings / API Keys page

To test this, open any post and go to the Post Settings and click Email newsletter. You can set an email where you want to send the test email. Then click Send test email.

Transactional Email Configuration

Next step is to update the configuration of Ghost on the server to send transactional emails through Mailgun. This is needed to send confirmation emails to anyone who signs up for your newsletter through your form. They don't get added as a member until they click on the confirmation link so it's critical that they receive this email.

Get Mailgun SMTP credentials

First, in Mailgun, navigate to Domain settings under Sending. There you’ll find your SMTP credentials. This is different from the API key you found in the previous step.

In addition to this information you’ll need the a password, which can be obtained by clicking the Reset Password button. Keep these details for future reference.

Add credentials to config.production.json

Open the config.production.json file from your ghost root directory in any code editor and add the following mail configuration, making sure to update the values to the same credentials shown in your own Mailgun SMTP settings:

"mail": {  
  "transport": "SMTP",  
  "options": {  
    "service": "Mailgun",   
    "auth": {  
      "user": "",  
      "pass": "your_password"  

The user is the email address shown in Mailgun under "Login".

After adding all the settings and saving the config file, restart Ghost:

ghost restart   

And that's it! You can now try signing up in your newly created form. You should get an email in your inbox to confirm the signup and on clicking the confirmation, the member gets added to your member list.

Hope that helps!


Show Comments