Detecting newsletter subscriptions

Is there a way to detect from within a theme template which newsletters a member is subscribed to? I have a secondary newsletter that I think deserves its own dedicated subscribe/call-to-action widget, and I would like to hide this widget when members are viewing that newsletter’s archive if they are subscribed to it.

1 Like

Unfortunately, the @member object doesn’t include that information. However, when a member is logged in, you could call the /members/api/member/ endpoint.

The response will include a newsletters array, which includes all the newsletters the member is subscribed to:

{
    "uuid": "some-uuid",
    "email": "example@example.com",
    "name": "John Doe",
    "firstname": "John",
    "expertise": null,
    "avatar_image": "https://www.gravatar.com/avatar/somegravatar",
    "subscribed": false,
    "subscriptions": [],
    "paid": false,
    "created_at": "2024-01-01T00:00:00.000Z",
    "enable_comment_notifications": true,
    "newsletters": [
        {
            "id": "123456789
            "uuid": "some-uuid"
            "name": "Newsletter 1",
            "description": "Some description",
            "sort_order": 0
        },
        {
            "id": "987654321",
            "uuid": "some-uuid",
            "name": "Newsletter 2",
            "description": "Some description",
            "sort_order": 0
        }
    ],
    "email_suppression": {
        "suppressed": false,
        "info": null
    }
}
1 Like

Thank you for the suggestion. I will try this and report back on the results.

1 Like

Since the Ghost Admin API is designed for server-side use, how would you recommend approaching this? I am thinking perhaps I could run my Ghost API calls on Cloudflare Workers and make a call to that from a script tag in my theme template.

Whoops, sorry for missing that part.

That endpoint is technically part of the admin API, yeah. But it can safely be called client-side, since it doesn’t need the usual authentication the admin API needs.

When a user isn’t logged in (e.g. no cookies are sent with the request), it will return status 204. When the user is logged in (and the member cookies are sent with the request), it will return status 200 and the information I pasted above.

Hope that helps!

1 Like

This worked like a charm! It never occurred to me that I could simply call this endpoint from within a theme template and get a response if the visitor is a logged in member.

Here is the final code I added to a script tag in my template. It assumes you have a <div id="subscription-cta"></div> somewhere in your template.

document.addEventListener('DOMContentLoaded', (event) => {
    fetch('/members/api/member/')
    .then(response => {
      return response.json()
    }).then(member => {
      if (member) {
        console.log('Member is signed in')
        if (member.newsletters) {
          const subscribed = member.newsletters.some(newsletter => newsletter.name === 'My Newsletter')

          if (subscribed) {
            console.log('Member is subscribed to My Newsletter')
            showThanksMessage()
          } else {
            console.log('Member is not subscribed to My Newsletter')
            showSubscribeButton()
          }
        }
      } else {
        console.log('Member is not signed in')
        showSubscribeButton()
      }
    })
  })

  function showSubscribeButton () {
    const div = document.getElementById('subscription-cta')
    if (div) {
      div.innerHTML = '<a href="#" class="button primary">Subscribe</a>'
    }
  }
  function showThanksMessage () {
    const div = document.getElementById('subscription-cta')
    if (div) {
      div.innerHTML = '<p class="thanks">✅ Thank you for subscribing</p>'
    }
  }

Thank you again for your assistance, jannis.

1 Like