How to Get Memberful to Work with Cached WordPress Sites

On a recent project, I was implementing Memberful with a WordPress site. If you don’t know, Memberful is both a service and a WordPress plugin that allows you to charge people to view some or all of the content on your site. In general, it seems like a great service so far.

Except, it was not working with caching on this particular WordPress site, which is hosted on Siteground.

The Problem

Or just skip to the solution.

Specifically, if a user tried to login through Memberful’s overlay, it would log them in, however upon page refresh they still appeared to not be logged in. Refreshing the page solved the problem, but how would a user know to do that? And there was no way to trigger a refresh automatically, either, because the page didn’t recognize that the user was logged in, so is_user_logged_in() wasn’t recognized until the page was refreshed again, too.

I suspect this is not a SiteGround-specific issue, though, but rather any setup that involves caching WordPress sites and Memberful’s overlay.

screenshot of memberful's login screen
Memberful’s overlay login, which you add to your WordPress site to sync up Memberful and WP users.

Memberful’s support was very responsive, but they kept asking me to turn off cache completely, which is something I was willing to do while testing, but serving up a website that relies on PHP and a database to compile pages, like all WordPress sites do, is just not a longterm solution. Even when I did turn off all three layers of caching (in SiteGround’s CPanel, look for SuperCacher, or if you’re in the new interface, you can find these settings under Speed > Caching.

CPanel in SiteGround Accounts
SuperCacher setting SiteGround’s CPanel.
siteground's new interface
Caching settings in the new SiteGround interface, available to some customers as of March 2020.

The thing is, you don’t have to turn all of these off. I did so, and it had absolutely no effect one way or the other.

How to Fix It

1. First, you need to have some way to know if a post is protected by Memberful. Memberful does add things to the database when you mark a post as protected, but we put all of our protected content into one of two categories, so this worked for us (this is added to functions.php in your theme, or child theme if you didn’t build the theme you’re using):

function in_memberful() {
if (in_category(730) || in_category(731)) { // change these to the category IDs you're using
return true;
}
}

If you don’t want to add your protected content to specific categories, or tags, you could also check for post meta data that Memberful seems to add to all posts. This is untested, but between this code snippet and investigating your database, you should be able to figure out what to change here. Don’t use both the above and the immediately following function, or you’ll break your site.

function in_memberful() {
$memberful_check = get_post_meta( get_the_ID(), 'memberful_marketing_content');
if (!empty($memberful_check)) { // presumably you'd always have this meta field on a Memberful post
return true;
}
}

2. Then in your theme’s header.php, at the very top, before any other HTML is output, I do this:

<?php if (in_memberful()) {
session_start(); // this is needed to overwrite previous Cache-Control, etc., though "true" in the next line should be doing this anyway
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0", true); header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
} ?>

Remember, you have to put this at the top of header.php, before any HTML content.

That means before this:

<!DOCTYPE html>

…for most cases.

Essentially, this says, “If this post is marked as protected by Memberful, force the browser to ignore all cache and just load the page fresh.”

Ideally, Memberful will fix this, as using built in functions like wp_login_form() don’t suffer from this same problem.

Up Next: How to Verify Your GoDaddy Domain Name with Google Search Console