Skip to content

Using Cookies in WordPress, Part II: Cache-Busting with Ajax

Caching makes everything harder. If you’re writing good code and then you—and your clients, coworkers, etc.—are seeing absolutely no result, the issue is typically caching. In fact, a lovingly cited quote by Phil Karlton holds that “There are only two hard things in Computer Science: cache invalidation and naming things.”

The Challenge: Full-Page Caching

So it stands to reason that last week’s article on writing PHP cookies in WordPress has a big asterisk about caching. In particular, the full-page caching that makes our site fast (it’s the SiteGround SuperCacher’s dynamic caching, which we love) also causes cookies not to be retrieved.

To be more specific, it’s possible to save new cookies to the server, but the HTTP $_COOKIES object doesn’t reflect those changes, because the server’s not looking for changes: It’s serving a cached version of the entire page, headers included. This is beautifully explained (and was made clear to me) in this article by Nick Davis.

So following a puzzled (and puzzling) comment on the article, I had to turn off dynamic caching for the page to make the demo work—which, of course, may not be workable on a site which needs full-page caching and cookies. You shouldn’t have to choose one or the other.

The Solution: Ajax

It turns out there’s a solution, which makes use of Ajax. Ajax is a way to talk directly to your web server after your page loads—and then to update your page with the results of that conversation. It’s just what we need to get around a full-page cache, because our issue is as follows: the new cookie information is set in the server, but the server doesn’t look for it when it builds out the page. So we’re going to dive into the server and get that information out ourselves, using Ajax.


This works a lot like last week’s demo, but it:

  1. Doesn’t force page refreshes.
  2. Works with page caching (SiteGround’s dynamic caching) enabled on the page.

Our Sources

Our solution here is an elabortion of Nick Davis’s article, and a nice WP Engine article on cookies and WordPress caching. We’re also using a simple JS cookie library, as recommended by Paul Underwood.

This plugin is up on GitHub if you’d like to browse the full source. We’ll just be calling out bits of it below.

The Code

PHP

Relative to last week, we’re doing significantly less in PHP. We’re now doing three things:

1. Enqueue JavaScript Files

add_action( 'wp_enqueue_scripts', 'wpshout_cookie_scripts' );
function wpshout_cookie_scripts() {
	wp_enqueue_script( 'wpshout-js-cookie-demo', plugin_dir_url( __FILE__ ) . 'wpshout-js-cookie-demo.js', array( 'jquery', 'cookie' ) );
	wp_enqueue_script( 'cookie', plugin_dir_url( __FILE__ ) . 'cookie.js', array( 'jquery' ) );

	/* Telling the JS file where ajaxUrl is */
	wp_localize_script( 'wpshout-js-cookie-demo', 'ajaxUrl', array( 
		'url' => admin_url() . 'admin-ajax.php',
	) );
}

This code pulls in the two JS files we need: cookie.js, the external library for JavaScript cookies; and wpshout-js-cookie-demo.js, which relies on cookie.js.

The call to wp_localize_script() is our way of giving our JS file PHP variables. In our case, we need to do something common: Tell our script where Ajax requests should point to.

2. Handle Ajax Requests

add_action( 'wp_ajax_wpshout_get_fave_food_cookie', 'wpshout_get_fave_food_cookie' );
add_action( 'wp_ajax_nopriv_wpshout_get_fave_food_cookie', 'wpshout_get_fave_food_cookie' );
function wpshout_get_fave_food_cookie() {
	$cookie = $_POST['cookie'];
	echo $_COOKIE[ $cookie ];
	die;
}

This code does the server-side processing for our Ajax request. What it does, in words, is look up a specific member of the $_COOKIE superglobal array. We define which member that will be based on what we POST to Ajax with the name 'cookie'.

Once the $_COOKIE item is fetched, this code gives it back to the JS that called it using echo, and then stops executing.

3. Register Shortcodes

add_shortcode( 'js_cookie_demo', 'wpjcd_show_cookie_result' );
function wpjcd_show_cookie_result() {
	ob_start();
	echo '<div class="current-favorite"></div>';
	return ob_get_clean();
}
add_shortcode( 'js_cookie_form', 'wpjcd_show_cookie_form' );
function wpjcd_show_cookie_form() {
	ob_start(); ?>
		<div class="favorite-food-form">
			<label for="name">Fave Food:</label><br>
			<input type="text" class="favorite-food-input" placeholder="Cookies"><p><button class="favorite-food-submit">Submit</button></p>
		</div>
	<?php return ob_get_clean();
}

This piece of the code is similar to last week; it registers two WordPress shortcodes to display our “Favorite Food” form. More on shortcodes here and here if that would be helpful.

JavaScript

We’re using JavaScript to do quite a bit. We’ll discuss the two most important things:

Ajax Request

/* Ajax request to get current cookie despite caching */
$.post(
	ajaxUrl.url, 
	{
		'action': 'wpshout_get_fave_food_cookie',
		'cookie': cookieName,
	}, 
	function( response ) {
		console.log( response );
		fave = response;
		if( typeof( fave ) === 'undefined' ) {
			$( '.current-favorite' ).html( noFaveText );
		} else {
			$( '.current-favorite' ).html( faveText + fave );
		}
	}
);

This is the crux of this solution. Rather than ask the current page for what’s stored in $_COOKIE our JS makes a direct request to WordPress’s AjaxURL instead. The result is that we retrieve uncached results from the server.

When it gets the result, it publishes that result to the page, as the contents of the element with class current-favorite.

Again, if Ajax itself is unclear, please check out our earlier tutorial on the subject.

Updating Through Form

/* Update favorite food through form */
$( '.favorite-food-submit' ).click(function() {
	cookie.remove( cookieName );

	cookie.set( cookieName, faveTyped, {
	   expires: 999, // Expires in 999 days
	   path: '/',
	});
			
	fave = cookie.get( cookieName );
	$( '.current-favorite' ).html( faveText + fave );
});

This code is what lets us set the cookie to a value specified by the user. Note that we don’t need to use Ajax for this piece: our problem isn’t setting things to $_COOKIE, it’s retrieving the new values despite caching.

To set the cookie itself, we’re first removing the old value with cookie.remove(), and then setting a new value with cookie.set(). Finally, we’re updating the form on the current page load with cookie.get() and jQuery. All three of these cookie. methods come from the cookie.js library, which simplifies working with cookies in JavaScript.

Cache Busted, Cookies Delicious!

Well! I hope this gives you a sense of how to work with cookies in a cached environment. You do have to know some Ajax, but the beautiful thing about it once it works is that it’s not only cache-proof, but also dynamic—no browser refreshes needed.

If you have any questions or thoughts, we’d love to hear them in the comments below. Thanks for reading!

Yay! 🎉 You made it to the end of the article!
Fred Meyer

3 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
PHP Cookie, Raw Cookie and How to Cookie with Caching System
September 27, 2016 4:00 am

[…] data we want, then using JavaScript to get the results and change the DOM. You can check out the following article from WPShout for a functional demo on how to use cookies with a full page caching […]

Andrew
May 28, 2016 3:45 pm

Thanks for the powerful article. Any suggestions on how to create shortcodes that could be used to wrap content in ajax (in posts and in wp templates)? This way, shortcodes could be used to prevent content, forms, etc from being cached. Thanks for any suggestions.

How to use cookies with a cached WordPress website (on WP Engine)
December 31, 2015 1:39 pm

[…] PS If you are looking for a ‘proper’ cookie busting with AJAX on WP Engine example, check out this post. […]

Or start the conversation in our Facebook group for WordPress professionals. Find answers, share tips, and get help from other WordPress experts. Join now (it’s free)!

3
0
Would love your thoughts, please comment.x

Most Searched Articles

Best JavaScript Libraries and Frameworks: Try These 14 in 2024

In this post, we look at the best JavaScript libraries and frameworks to try out this year. Why? Well, with JavaScript being available in every web browser, this makes it the most accessible programming language of ...

20 Best Free WordPress Themes for 2024 (Responsive, Mobile-Ready, Beautiful)

If you're looking for only the best free WordPress themes in the market for this year, then you're in the right place. We have more than enough such themes for you right ...

12 Best WordPress Hosting Providers of 2024 Compared and Tested

Looking for the best WordPress hosting that you can actually afford? We did the testing for you. Here are 10+ best hosts on the market ...

Handpicked Articles

How to Make a WordPress Website: Ultimate Guide for All Users – Beginners, Intermediate, Advanced

Many people wonder how to make a WordPress website. They’ve heard about WordPress, its incredible popularity, excellent features and designs, and now they want to join the pack and build a WordPress website of their own. So, where does one get ...

How to Start an Ecommerce Business: Ultimate Guide for 2024

Is this going to be the year you learn how to start an eCommerce business from scratch? You’re certainly in the right place! This guide will give you a roadmap to getting from 0 to a fully functional eCommerce business. ...