When you have a WordPress site on Cloudflare with a Cache Everything page rule, you probably know this: everything includes preview pages!
This post suggests a way to make sure Cloudflare does not cache the preview page even when you set your Cloudflare cache level to “cache everything” with a page rule.
Since the HTML is generated dynamically by WordPress, every visit runs the whole WordPress machine to generate the HTML for a page, even the if the content of the page is static. That causes most WordPress sites to become slow, especially when it comes to “time to first byte”, or TTFB, And TTFB is important because it impacts the final page speed.
To speed things up, you can request that Clouflare cache the HTML, so when visitors come to a page that has been recently requested, Clouflare returns the HTML it has in cache, instead of requesting your server to generate it again. And that can have a dramatic effect on your site’s speed.
But everything means everything, and that includes the pages generated by WordPress when you are editing a post or page and request a “preview” of what you are doing. The first time you see the preview, it shows what you are working on. The second time, it will show the page as cached by Cloudflare, without the most recent modifications you may have done to your page.
Busting the Cache
Normally, a preview page will have an URL like this:
One way to avoid it being cached by Cloudflare under a cache-everything page rule is to add another page rule:
Cache Level: Bypass
But that means you need to spend one of your plan’s allocated page rules with something that will be of occasional use. Also, it only benefits the person who’s editing the page or post, its author. Instead, if you avoid this page rule, you use the entitlement instead for something that impacts the whole site, such as a canonical redirect from naked domain to www, or vice-versa.
This is especially important if you have a small WordPress website running on a Cloudflare Free Plan, which only allows for 3 page rules (BTW, check our recommended solution to implement cache everything on a WordPress site with static content using only 2 page rules.)
A Cache Buster Just for Preview
The HTML contains a hidden button and the JS code will check whether the
preview= query string is present. If it is, it will display the button, with an
onclick() element that will reload the page and add a random string as a second query string value.
So your preview page that initially had an URL like:
Will be reloaded as:
a1b2c3 is the random alphanumeric string added to it.
Since Cloudflare treats each page with a distinct query string as a separate page for caching purposes when you set the cache level to “cache everything”, the new URL will be fetched straight from your origin, showing the preview of the page or post you are working on.
Adding the HTML to WordPress
There are a few ways you can add the HTML above to your WordPress site.
The easiest way is to make use of one of the several plugins in the wordpress.org plugin repository that let you add code to your pages and posts.
Ideally, the plugin should already come with the option to only show in the preview pages (in this case you should use the HTML below).
Custom HTML Widget
You can also add the HTML to a WordPress widget of the type Custom HTML, though this solution has its limitations. It’s important not to set a title, otherwise the title would show to all pages, preview or not. Also, depending on the theme your site is using, the HTML should be present in every page, but its content (the “preview cache bust” button) will only display for pages with the
preview=true in the URL as part of the query string.
When testing this solution in a standard WordPress installation with the Twenty Twenty default theme, it worked fine. But depending on what theme you use, you may need to make sure the appearance of non-preview pages is not altered by the conditional widget we just added. If some element appears where they shouldn’t, like white backgrounds where the widget should display, for instance, you may want to read on and see if the solution involving adding a couple of PHP lines to one or more of your child theme files may work for you.
A Better Way
If your site has (as it should) a child theme, you may want to benefit from WordPress’ built-in function
In a default WordPress installation with the Twenty Twenty theme, you could for instance edit the
header.php file of your child theme and add the following PHP code right below the HTML
<?php if ( is_preview() ): ?> The streamlined HTML goes here <?php endif; ?>
if condition will evaluate if the page being generated is a preview page, and only run the code between the
if condition, no hidden buttons will need to appear in the HTML of other pages, avoiding any possible CSS issues for those other pages.
Placing it right below the
<body> tag will assure that the button will show at the very top of the page, and not interfering otherwise with the page layout.
For sites with other themes, you should place the PHP lines immediately after the HTML
<body> tag, wherever the theme template files would insert it. (If you don’t know where that is, you can use the excellent String Locator plugin to quickly find which of your child theme’s files adds the
<body> tag. Ignore results for CSS files, and you should find it right away.)
Please send any comments as replies to the tweet below. Click on the date of the tweet to open it on Twitter.