How to disable cache for logged in users on dynamic wordpress site

I use Cloudflare heavily on all my wordpress sites. On pokerdiy I use the MyListings Theme which uses an AJAX login and Woo Commerce. The user never sees the default wordpress admin dashboards and control panels by design. However, they should see their logged in pages and at the top right of every page it will show their name and a different menu for logged in users.

I now have caching issues with logged in users - My theory is that Cloudflare cannot determine when a user is logged in or not, so it is displaying the cached anonymous logged out view.

When I disable cloudflare the site works fine.

Reading on Cloudflare it sounds like “Bypass Cache by Cookie” is the only option to tell whether or not a user is logged in. However, this is a $200 Business license on Cloudflare which is out of the question for a hobby site.

This is a long read, but halfway down someone suggests that the headers WP returns should be respected by CloudFlare: https://support.cloudflare.com/hc/en-us/articles/236166048

Another person suggested using Cloudflare workers to replicate the “Bypass cache by cookie” functionality that costs $200 per month.

How can I use Cloudflare caching on a Wordpress site that uses front-end user logins?

Those are your two options. Business Plan, or Workers that charge by use. You’ll have to estimate the Workers cost based upon hits to the URLs covered by the Worker route.

Here’s the code I use, courtesy of @eva2000

// Stop CF edge from caching your site when specific wordpress cookies are present
addEventListener('fetch', event => {
  event.respondWith(noCacheOnCookie(event.request))
})

async function noCacheOnCookie(request) {
  // Determine which group this request is in.
  const cookie = request.headers.get('Cookie')
  const cacheSeconds = 604800
  if (cookie 
    && (
      cookie.includes(`wordpress_logged`)
      || cookie.includes(`comment_`)
      || cookie.includes(`wordpress_sec`)
    )) {
    const bustedRequest = new Request(request, { cf: { cacheTtl: -1 } })
    const response = await fetch(bustedRequest)

    const newHeaders = new Headers(response.headers)
    newHeaders.append('wp-cache-busted', `true`)
    return new Response(response.body, {
      status: response.status,
      statusText: response.statusText,
      headers: newHeaders
    })
  } else {
    // Edge Cache for 7 days
    return fetch(new Request(request, { cf: { cacheTtl: cacheSeconds } }))
  }
}

Great thank you - it looks like workers pricing plan allows 100k hits a DAY which is ample - https://www.cloudflare.com/en-au/products/cloudflare-workers/

That free one doesn’t work on a custom domain. I think. That page doesn’t make it clear, but I think that’s the deal.

FYI, I found a similar answer here and after a bit of trial and error with Workers I have it all working now!

It was a bit tricky to set up and you have to be so careful with the Page Rules but it’s humming now and I save $200 a month :wink: I signed up for the Unlimited Workers for 1 month ($5) but I’ll cancel before next renewal and confirm if the free one works too (documentation is patchy!)

Thanks for pointing me in right direction @sdayman

1 Like

Have you considered the CometCache plugin? I’ve had great success with it.

1 Like

I am using WP-rocket. But I still want caching at the DNS server level.

This topic was automatically closed after 30 days. New replies are no longer allowed.