We are using Easy Digital Downloads (EDD) and various of their add-ons to sell Advanced Ads on our own website. At the same time, we use website caching provided by the awesome WP Rocket plugin.
For a long time, we went with the quasi default setup and had caching disabled for all logged-in users (i.e., customers and admins) and for those who added an item to their card. We also had caching disabled on product pages like for Advanced Ads Pro due to so much magic going on by EDD on those pages.
With the product pages driving in a lot of traffic for SEO and our growing customer base, our website was not providing the best experience for more and more users due to a lack in page speed.
So we went on a months-long journey to trying to make Easy Digital Downloads work with a fully cached page. We didn’t succeed eventually and had to revert many options but I didn’t want to get the learnings we had going to waste, especially with EDD itself providing very little information on this topics and the pitfalls.
Preparing the customer account
The only section we wanted to keep from being cached was the customer account.
We ended up doing more work here then just to prepare for caching, but one of our main tasks was to move the download section from the All Access package into the customer account. Before, we just added it to the add-ons page in the frontend.
After that, we only had to whitelist /account
and any subpages in WP Rocket to prevent them from caching.
WP Rocket: Enabling cache for all users, except of admins
WP Rocket has an option in the backend to enable caching for logged-in users. However, we wanted to exclude the administrator role specifically from that.
For logged-in users, WP Rocket uses individual cache files for each user, which is for us almost as not using caching at all. We wanted logged-in users share the same caching files.
Both seem to be possible using the custom code they provided on their User Cache and Disable cache for logged-in administrators pages. However, after going back end forth with an amazing support rep, the WP Rocket team discovered that it was not possible to combine those options.
We ended up enabling the same cache for all users including admins. This is when I built a WP Toolbar script that works also on cached sites.
I am still using that script instead of the default WordPress Toolbar even though we switched back to not caching pages for any logged-in user.
Rewriting the EDD purchase button
The biggest pain point was the EDD purchase button. That’s the one you place automatically or using the [purchase_link id="123"]
shortcode.
The button comes with a lot of dynamics, depending on your settings:
- Converts into a “Checkout” link when you have the product in your cart
- Converts into “Download” if the product is in the purchased “All Access” package
- Show upgrade links below the button if set up with Software Licensing
I spend some time unregistering hooks and creating a copy of the button for our site, which worked well, eventually.
Until…
Nonces
At some point after launching our fully cached website, a user made us aware that the add-to-cart buttons don’t work. When checking, I noticed that it throws an error without saying details.
I verified that this was also the case with the default EDD purchase buttons and with just the basic EDD plugin, WP Rocket, and a default theme.
Luckily, I had an early hunch that proved correct: EDD is, correctly, using a nonce to secure the call from the purchase-button in the frontend when using admin-ajax.php
.
At this point, we had the following options:
- Reducing the cache lifetime in WP Rocket to 12 or fewer hours, since this is how long nonces are valid.
- Extend the lifetime of the nonce. Simple to do through a filter but a potential security risk if done too extensively.
- Use static add-to-cart buttons implemented with more custom code.
For now, I opted for solution 1. WP Rocket has a cache preloader, which makes sure that most pages are cached when the first user visits them.
Status
Due to so many issues and lack of time to fix them properly, our EDD and caching setup is back to not caching logged-in users. We are still delivering cached sites to users with items in their cart, though.
After decreasing the cache lifespan, our product pages are cached again.
If time allows, I intend to implement static add-to-cart buttons on product pages and in the sidebar of articles and extend the cache lifespan back to 30 days.
My long-term goal is to actually move our store to a separate WordPress installation that would then not need any caching or customizations to make it work.