Cloudflare Setup for WooCommerce & WordPress: Complete Guide
A safe Cloudflare setup for WooCommerce has three separate jobs: protect the origin server, cache static files, and decide which HTML pages can be shared between visitors. Cloudflare does the first two reasonably well with little configuration. It does not cache WordPress HTML by default.
That distinction matters. If you only move your nameservers to Cloudflare, your images, CSS and JavaScript can be served from its edge network, but each shop, category and product page still goes back to WordPress for its HTML.
Free: Super Page Cache can create an HTML Cache Rule on Cloudflare Free. Paid: APO costs $5 per month on Free and is included with Pro and above. Both normally bypass logged-in visitors and anyone carrying a WooCommerce basket. Caching those visitors safely needs personal parts separated from the shared HTML.
What Cloudflare caches by default
Cloudflare caches recognised static file extensions by default. Its own documentation says that HTML and JSON are not cached unless you add a Cache Rule or use another product such as Automatic Platform Optimization (APO).
That gives you a useful first layer:
- DNS, TLS and HTTP/2 or HTTP/3 at Cloudflare’s edge
- DDoS protection before traffic reaches your server
- caching for images, stylesheets, scripts, fonts and other static files
- firewall and bot controls, depending on your plan
It does not remove PHP, WordPress, WooCommerce or database generation time from an ordinary page request. On an HTML response, CF-Cache-Status: DYNAMIC is therefore expected until you enable HTML caching.
Before enabling full-page caching
Move carefully. A nameserver change can be completed without downtime, but it is not inherently a zero-downtime operation. Missing DNS records, a wrong origin address or the wrong SSL mode can still take a working shop offline.
- Import and verify every DNS record before changing nameservers.
- Proxy the web records through Cloudflare, shown by the orange cloud in DNS.
- Use Full (strict) SSL once a valid certificate is installed at the origin.
- Test wp-admin, login, password resets, checkout, payment callbacks, webhooks, REST API calls and scheduled jobs.
- If you restrict the origin firewall to Cloudflare addresses, keep a tested recovery route and update Cloudflare’s published IP ranges.
- Restore the real visitor IP at Nginx, Apache or LiteSpeed so logs, rate limits and Fail2ban act on the visitor rather than a Cloudflare proxy.
Do not add a site-wide “Cache Everything” rule to a WooCommerce store without exclusions. It can cache a basket, account page, nonce or customer-specific price and serve it to somebody else.
Free full-page HTML caching with Super Page Cache
Super Page Cache, formerly WP Cloudflare Super Page Cache, enables HTML edge caching on Cloudflare’s Free plan. I downloaded and inspected version 5.3.3, released 12 August 2026, rather than relying on the plugin description.
The current plugin does four relevant things:
- It creates a rule in Cloudflare’s
http_request_cache_settingsphase. - That rule sets the matched request to eligible for caching.
- Its expression excludes configured cookies and private paths, including WordPress login and WooCommerce session signals.
- WordPress sends an
s-maxagecache lifetime and the plugin purges affected URLs when content, stock or scheduled sales change.
Cloudflare currently makes Cache Rules available on every plan, with 10 rules on Free. The plugin uses that documented feature. It is not tricking Cloudflare into caching HTML.
What the ?swcfpc=1 parameter actually does
Older versions became known for adding ?swcfpc=1 to internal links for a logged-in user. The parameter changes the URL, and therefore the cache key, so the logged-in request cannot receive the anonymous copy stored under the clean URL.
It was a cache buster, not a way to cache logged-in visitors. WordPress still generated their page.
The current plugin retains that code as an optional fallback, including JavaScript which rewrites internal links and a redirect which cleans the parameter from anonymous visits. However, Remove Cache Buster Query Parameter is enabled by default. With that default, it does not append the parameter. Modern Cache Rules instead exclude requests whose Cookie header contains configured WordPress or WooCommerce cookie names.
This history is easy to confuse with a Free-plan workaround. The old Page Rules feature reserved “Bypass Cache on Cookie” for Business and Enterprise, so the query parameter emulated a safe bypass on cheaper plans. It did not evade a ban on HTML caching.
Leave cache-buster removal enabled unless you have proved that your particular Cloudflare rule cannot recognise the login cookies. Rewriting every internal link creates duplicate-looking URLs, complicates analytics and needs canonical redirects if one leaks to a crawler.
Does free HTML caching break Cloudflare’s terms?
I could not substantiate that warning. Cloudflare says its CDN was designed to serve webpages, its documentation explicitly offers Cache Rules on the Free plan, and its current product limits focus on disproportionate delivery of video and other large files hosted outside Cloudflare services.
Terms and plan limits can change, so check the current agreement for your own use. There is no sound basis for telling a normal WordPress site that caching its HTML through a documented Free-plan Cache Rule is itself a breach.
How to set up the free route
- Install Super Page Cache from WordPress.org.
- Disable page caching in WP Rocket, LiteSpeed Cache, W3 Total Cache or another plugin. You can keep its CSS, JavaScript and image optimisation if those features work independently.
- Connect Cloudflare with a scoped API token rather than the Global API Key.
- Select the correct Cloudflare zone and enable Cloudflare CDN and caching. The plugin creates its own
[DO NOT EDIT] WP Super Page Cache Plugin rules for...Cache Rule. - Keep Cart, Checkout, checkout payment endpoints, My Account, wp-admin, login, REST endpoints and WooCommerce API endpoints excluded.
- Keep WordPress login, WooCommerce session, basket, wishlist and other personal cookies in the exclusion list.
- Purge the cache, open an incognito window and request the same catalogue URL twice.
The plugin’s own headers help with diagnosis. X-WP-CF-Super-Cache-Active: 1 means the page was marked for Cloudflare caching. CF-Cache-Status: MISS on the first request followed by HIT on the second means the edge copy is working.
Cloudflare normally refuses to cache a response which sets a cookie. Super Page Cache can strip response cookies, but that option is off by default. A plugin may be setting a cookie because the response really is personal. Identify the cookie and its purpose before removing it.
Paid full-page HTML caching with Cloudflare APO
Automatic Platform Optimization for WordPress is Cloudflare’s own paid HTML caching route.
- Free plan: APO is a $5 per month add-on.
- Pro: $20 per month billed annually or $25 monthly, with APO included.
- Business and Enterprise: APO is included.
Prices checked 14 August 2026. Cloudflare can change them, so confirm the dashboard price before buying.
APO uses Cloudflare’s WordPress plugin, Workers and KV as well as the ordinary edge cache. A page requested in one region can be made available from KV to other Cloudflare locations, reducing the cold-cache problem of a cache which only fills after a request reaches each individual edge.
With the WordPress plugin active, Cloudflare documents a 30-day edge cache lifetime and invalidation after a WordPress change, normally within 30 seconds. It also knows that common marketing parameters such as utm_source, gclid and fbclid can use the normal cached page.
What APO does not provide
APO does not make every WooCommerce visitor cacheable. Cloudflare always bypasses APO for cookie prefixes including wordpress, woocommerce_, yith_wcwl_session_ and several other application cookies. In practice, that means:
- logged-in customers still run WordPress for ordinary page views
- visitors carrying a WooCommerce basket still run WordPress for ordinary page views
- Cart, Checkout and My Account still need to remain private
- a custom pricing, membership, wishlist or currency plugin may introduce another bypass cookie
- APO is not a Redis or Memcached object cache
- APO does not optimise slow PHP, SQL, wp-admin, checkout, uncached API calls or an edge-cache miss
- Cloudflare’s WordPress APO plugin does not support WordPress multisite
Cloudflare recommends starting APO with other page-caching plugins disabled, proving that APO works, and only then testing whether the other plugin adds value without causing conflicting headers or purges.
Free Cache Rules versus paid APO
Super Page Cache + Cloudflare Free
- Cost: $0 to Cloudflare
- HTML edge caching: yes
- Cache fill: ordinary Cloudflare edge cache
- Purging: automatic WordPress purging
- Origin disk cache: optional
- Logged-in pages: not cached
- Basket-holder catalogue pages: not cached
- Object cache: not included
Cloudflare APO
- Cost: $5/month on Free; included with Pro and above
- HTML edge caching: yes
- Cache fill: edge cache plus Workers/KV to reduce global cold starts
- Purging: automatic WordPress purging
- Origin disk cache: not provided
- Logged-in pages: not cached
- Basket-holder catalogue pages: not cached
- Object cache: not included
The free route gives a lot away for nothing. APO is cleaner if you want Cloudflare’s supported WordPress integration and more consistent cache availability across its network. Neither solves the hard WooCommerce problem: the shoppers most likely to buy are the ones most likely to carry a basket or have an account, and both standard configurations send them back to PHP.
WooCommerce pages and signals which must stay private
For an ordinary anonymous page-cache setup, bypass at least:
- the separate Cart or Basket page
- Checkout, order-pay and order-received pages
- My Account and all account endpoints
- wp-admin, login, previews and password-protected content
- POST requests, WooCommerce AJAX, payment callbacks, webhooks and REST/API requests
- searches, filters, currency changes and other query strings which genuinely change the result
- requests carrying login, basket, session, customer, wishlist or other personal cookies
Tracking parameters are different. A Facebook, Google or email tracking parameter normally should not create another HTML copy or force an origin request. APO has an allowlist for common tracking parameters. With Cache Rules, normalise or ignore only parameters you have confirmed do not change the page.
Test at least these states after every caching change:
- New logged-out visitor with no basket.
- Logged-out visitor with an item in the basket.
- Logged-in customer with an empty basket.
- Logged-in customer with an item in the basket.
- Any country, currency, role, membership or dynamic-pricing state your shop supports.
Correctness comes before hit ratio. Check prices, tax, stock, Add to Cart state, mini-cart contents, wishlists, customer names and notices as well as the main page HTML.
Cache catalogue pages for every visitor
There is a third level beyond both standard approaches. Eligible shop, category, product and content pages can use one shared Cloudflare cache even when the visitor is logged in or carrying a basket. The private parts are then loaded separately for that visitor through a fast AJAX request.
The shared HTML must not contain customer data. Depending on the shop, the personal layer can include:
- role-based, customer-specific, country-based or dynamic prices
- tax display, currency and geolocated availability
- live stock and Add to Cart state
- basket count, mini-cart and fast-cart panels
- wishlists, loyalty balances and recently viewed products
- account names, membership details and customer-specific notices
Cart, Checkout, My Account and any other genuinely private page remain outside the shared cache. The gain is that adding an item to the basket no longer makes every catalogue page uncached for the rest of that visit.
This is not a safe one-click Cloudflare rule. The theme, active plugins, must-use plugins, host plugins, snippets and child-theme code need to be scanned for output and cookies which vary by visitor. Each personal region then needs one of three decisions: load it after the cached page, exclude the page, or change when the cookie is set.
Start by running the free Super Speedy Performance Analysis. It identifies which plugins and queries make an uncached request slow. Those measurements still matter for cache misses, checkout, wp-admin and every page you deliberately keep private.
If you want the shared-cache layer implemented for logged-in customers and basket holders, see the WooCommerce Full-Page Caching Implementation. It includes the plugin and cookie survey, store-specific compatibility code, Cloudflare rules, staging tests and production verification.
Verify Cloudflare page caching
Run the same request twice. The Accept header matters for APO:
curl -sI -H 'Accept: text/html' https://example.com/shop/
curl -sI -H 'Accept: text/html' https://example.com/shop/
For a normal cacheable anonymous page, expect the first response to be MISS and a later response from the same Cloudflare location to be HIT.
With APO, also look for cf-apo-via and cf-edge-cache: cache,platform=wordpress. With Super Page Cache, look for X-WP-CF-Super-Cache-Active: 1 and its disk-cache header if disk caching is enabled.
Common meanings:
CF-Cache-Status: HIT: Cloudflare served the cached response.MISS: eligible, but this edge did not yet have a fresh copy.DYNAMIC: HTML was not eligible at request time, usually because no HTML Cache Rule matched.BYPASS: it was considered for caching, but a rule, cookie,Set-Cookieor origin cache header prevented storage.
Do not test only while logged into wp-admin. In a standard APO or Super Page Cache setup, that request should bypass. Use an incognito window for the anonymous HIT, then repeat the test with a basket and a customer login to prove that personal data remains correct.
Configure Cloudflare security without breaking the shop
The old version of this guide recommended legacy PHP, Specials and WordPress rulesets, disabled specific old rule IDs globally, and challenged whole continents. That advice has aged badly.
Use Cloudflare’s current Managed Rulesets and Security Events instead:
- Enable the managed ruleset available on your plan.
- Watch Security Events while testing login, wp-admin editing, checkout, account forms, REST calls and webhooks.
- If a legitimate request is blocked, identify the exact managed rule and request path.
- Add the narrowest possible exception for that rule and that path. Do not disable a whole ruleset because one editor request is a false positive.
- Use rate limits or Managed Challenge against behaviour you have actually measured. Do not challenge an entire continent if you sell to legitimate visitors there.
Cloudflare is the first layer, not the only layer. Keep WordPress and plugins updated, protect the origin from direct access where practical, use strong authentication, and keep tested backups.
Further reading
- Cloudflare default cache behaviour: why HTML starts as
DYNAMIC - Cloudflare Cache Rules: current availability and rule behaviour
- Cloudflare APO query parameters and bypass cookies: what APO always sends to the origin
- Configuring Nginx to pass real IP addresses from Cloudflare: keep logs and Fail2ban accurate

You haven't even addressed the checkout or basket. How come?