DEV Community

Ryan Feigenbaum
Ryan Feigenbaum

Posted on • Originally published at ryanfeigenbaum.com on

Create a Dynamic CTA in Ghost

Create a Dynamic CTA in Ghost

Getting someone to do something is hard. Asking them to type their email or to click a button isn't a foregone conclusion, you need to show them why the effort is worthwhile.

Clicking is hardwork 😅

But as a creator, it's also hard to come up with effective CTAs.

With Ghost's templating layer, you can create more than your run-of-the-mill CTA by generating dynamic copy to increase engagement. Below, I'll show you how to easily create these dynamic CTAs in your post template.

The Basic CTA

We'll start with a simple CTA that asks our readers to sign up for a free newsletter.

Ghost provides some template magic we can use to add a signup form to any page. By adding the data-members-form attribute to a form element, we can tell Ghost to capture the subscriber's email and initiate a signup flow.

To make this work, you also need to add the data-members-email attribute to an input element and include a button to submit the form.

<p>Your life is missing something...</p>

<p>Sign up for our free newsletter and get the goodness right in your inbox.</p>

<form class="form" data-members-form >
  <label>Email <input type="email" required data-members-email />
  </label>
  <button>
    <span class="loading">Loading...</span>
    <span class="default">Sign Up</span>
    <span class="success">Check Your Inbox!</span>
    <span class="error">Error! Try again</span>
  </button>
</form>
Enter fullscreen mode Exit fullscreen mode

Basic CTA

Ghost's template magic also automatically adds state to your form by toggling classes on the form element. These classes will be merged with existing classes and removed when state is updated.

  • <form class="loading"...: added after the user clicks submit
  • <form class="success"...: added when signup is successful
  • <form class="error"...: added when signup is unsuccessful

Before moving on, we can make an immediate improvement to user experience. Right now, this CTA will be present wherever it's added to a theme. That means a user will see it, even if they're already a member, which can be confusing—why am I seeing this signup form if I'm already a member?

By using the @member object and the {{#if}} helper, you can control when the signup form is displayed. The caret (^) in front of if in the code below inverts the if helper and means: show this content if the current user is not a signed-in member. In other words, the CTA will only show to users who are not signed in.

{{^if @member}}

  <form class="form" data-members-form>
    ...
  </form>

{{/if}}
Enter fullscreen mode Exit fullscreen mode

Using the @member object

Styling the Sign Up Form

To show and hide the default, loading, success, and error states, you need to add a bit of CSS, as shown below.

In the markup above, state is indicated via text ("Loading..."), but you could just as easily use icons instead of or in addition to the text—the principle would be the same.

/* Hide stateful content */
.form .loading, 
.form .success,
.form .error {
    display: none;
}

/* Show stateful content */
.loading .loading,
.success .success,
.error .error {
    display: initial;
}

/* Hide default when stateful content is shown */
.loading .default,
.success .default,
.error .default {
    display: none;
}
Enter fullscreen mode Exit fullscreen mode

Styling to hide and show state

The Dynamic CTA

Member data isn't all we have access to via the Ghost template layer. Within the context of a post, we have access to its data, which includes its title, tag, and more.

We can use this data to generate a dynamic CTA.

{{! Make sure you're in the post context}}
{{#post}}

  {{! Only show the CTA if user is not a signed-in user }}
  {{^if @member}}

    <p>What if you never had the chance to read <em>{{title}}</em> or my other articles about 
    <a href={{primary_tag.url}}>{{primary_tag.name}}</a>
    ?</p>

    <p>Avoid the possibility of your life getting much worse by subscribing to my newsletter. It's totally free.</p>

    <form class="form" data-members-form>
      <label>Email <input type="email" required data-members-email />
      </label>
      <button>
        <span class="loading">Loading...</span>
        <span class="default">Sign Up</span>
        <span class="success">Check Your Inbox!</span>
        <span class="error">Error! Try again</span>
      </button>
    </form>

  {{/if}}

{{/post}}
Enter fullscreen mode Exit fullscreen mode

Dynamic CTA

While you'll need to find copy that'll suit your needs, the idea here is to update the CTA automatically based on the post's data. Instead of just saying, "Sign up for my wonderful newsletter," you can say, "Reading Title of My Article was truly wonderful, wasn't it? Don't miss other posts about x topic and sign up for my newsletter."

In the example above, I reference the article's title, its primary tag, and the link to that tag, so the reader can explore other posts on the same subject. Within the post object, you also have access to the post's author(s), description, publication date, excerpt, and more, all of which can be used to build creative CTAs to grow your audience.

Incorporating this data into a post's CTA is only a very small part of the battle of formulating an effective call to action. I hope, though, that having a few more tools at hand will spur your creativity in crafting kick-ass copy, and if I can have you take away anything from this tutorial, it's that your life will surely be much better if you sign up for my newsletter.

Top comments (0)