A Crash Course in AJAX for WordPress

Fred and I were just talking the other day about how initially-confusing the way you do Ajax requests in WordPress was to us. Both of us, completely independently, encountered a plugin we were trying to understand, knew was using Ajax, and couldn’t for the life of us tell how. It’s just not obvious when you’re new to all the concepts involved.

And if you’re unsure what Ajax does, or even means, have no fear. We’ll start by getting on the same page about what — other than the brand of cleaning product that’s been on American store shelves for decades — we mean when we’re talking about Ajax. Hopefully by the time we’re done you’ll know what Ajax is, why you’d want to use it in a WordPress plugin (or theme), and how you’d write or read the relevant WordPress code. Lets get started.

What We Mean by AJAX, and What It Saves Us From

Ajax first took hold in common usage around 2005, and the internet has been a lot better for it. If you’ve been on the internet this whole time, that may already give you a sense what Ajax has done for the web. If not, let’s explain.

Ajax allows for the data inside of a web page to be updated immediately without the page having to do a refresh.

In the early days of the web, the only time you’d get new data from the server was when you did a refresh of an existing page or clicked to a new page. And if you wanted a user of your site to submit a form, you’d have to have them see a big full page refresh as well. The cumulative result: your experience around the pages of a website was a bit jumpier than you experience today.

Enter AJAX

The new, more seamless web is mostly due to Ajax. Ajax stands for “Asynchronous Javascript and XML.” (It now actually rarely involves XML, but that’s a story for a different time…) It allows for the data inside of a web page to be updated immediately without the page having to do a refresh that the user sees as a full-page flicker.

With Ajax, you write some browser code (in JavaScript) to do something that previously required the user to manually visit a new page: send or receive new data from your site. You can, by inaccurate but approximate simile, think of the JavaScript “navigating to a new page for you and pulling back the data from the server.”

Then the JavaScript just makes that page data available in the context of your original page, without any obvious change for the user. This helps your user’s experience of continuity a lot, and also throws open whole new worlds of possibility for what you can do on a single web page.

An Introduction to Writing JavaScript for the Browser-side of AJAX

urlWhile this is a WordPress site, and you’ll use WordPress-specific functions to do your Ajax in a WordPress context, there’s not much that’s special about your JavaScript that makes Ajax requests, and receives the responses from the server. It’s possible to do Ajax in many different ways in JavaScript. But because we’re playing with WordPress, and most WordPress plugins use jQuery for their Ajax requests, our example will use it.

In a WordPress context, a basic jQuery Ajax request — in a separate file you enqueue correctly — will look something like this:

var format = 'U';
    type: "POST",
    url: "admin-ajax.php",
    data: { action: 'wps_get_time', format: format }
}).done(function( response ) {
    alert( response );

So what’s all this here? The goal of this script is simply to get a time from the server (possibly in a format the user specifies). Simple, and should let us see what Ajax does without getting bogged down in specifics.

The first line of the code (“format = 'U'“) just stands in for an actual user-supplied time format. The next line, which begins jQuery.ajax, is the meat of our work. If you notice, we specify a hash — a series of ordered pairs of data — in our call to the jQuery Ajax function.

The type: "POST" statement basically tells jQuery’s ajax function that it should send a POST request to the URL admin-ajax.php. (Quick summary of HTTP requests: GET requests are what you make when you browse the web, POST requests are how you send data.)

That URL may seem strange, but the way you do WordPress Ajax is almost always through the admin-ajax.php file bundled with the core of WordPress. Best practice states that you shouldn’t quite do it the way we’re doing it here — hardcoding the assumed file location — but for the scope of this tutorial I’ve left aside of the way you should make a variable of that URL’s real location available to your script with wp_localize_script.

The actual payload we’re sending is set in the data attribute: it’s an action name, which we’ll get to later, plus the specific time format we want. The action will almost always be a hard-coded string like you see there, but you can pass a lot more data to your receiving script than we are.

If you’re eagle-eyed, you noticed the .done(function() {}) after our ajax() call. This does what you might have guessed — it waits until the Ajax request is completed (the server replied with the data we asked for) — and then runs that function. All we’re doing with it here is a basic alert() — those pop-up dialogs — to show it worked. If we were really doing Ajax all throughout our JavaScript, the done function would be a great place to do your jQuery dance to put the data you got back from the server exactly where you want it in your HTML.

What PHP Does for the Server-Side Half of This AJAX Dance

The server-side part of Ajax in WordPress relies on that action: wps_get_time we had in our JavaScript, and also on the action hooks system of WordPress. Notice the naming similarity? (If you’re new to WordPress’s hook system, check out my conceptual outline of how they work.)

Essentially, when doing Ajax with WordPress, you don’t want to be making all your own endpoints from scratch — it’s complicated, prone to issues, and generally a waste of time — but rather just use the native action system to help you. This is awesome once you understand it’s available and happening, but this is exactly where both Fred and I got baffled when we first encountered it. The entire bit of relevant PHP for our system is here:

add_action( 'wp_ajax_wps_get_time', 'wps_get_time' );
add_action( 'wp_ajax_nopriv_wps_get_time', 'wps_get_time' );

function wps_get_time() {

    $format = $_POST['format'];

    echo date($format);

The first two lines there are exactly what Fred and I got caught on. We’re telling WordPress that for the an Ajax request with an action named ‘wps_get_time’, that it should call the wps_get_time PHP function. The wp_ajax_ and wp_ajax_nopriv_ prefixes are just to tell WordPress that these actions are attached to Ajax activity rather than conventional PHP workings.

The next thing you’re probably wondering is: What’s that _nopriv thing? Well because all our Ajax does is this case is tell the server’s time, and because we’re not actually changing any data in our WordPress site, we don’t want to exclude users who aren’t logged in from our awesome “endpoint.” _nopriv is how you tell WordPress that your action shouldn’t just be available to logged in users of your WordPress site (which is the default for the wp_ajax_ prefix), but to the whole world.

three-handsome-clocksThe PHP function that our endpoint uses is pretty simple. We’re accessing the format variable that we passed over in our Ajax request from JavaScript, and we’re using that to get a formatted time from PHP using the date() function.

If you return instead of echoing, you’ll be getting no data in your JavaScript.

The really important things to remember about Ajax in WordPress are the last two lines. We’re echoing a value so that it’s rendered into the “page” that JavaScript went and navigated to. If you instead inadvertently return, you’ll be getting no data in your JavaScript.

The die() is a self-explanatory PHP command that stops the execution of the rest of the script. You typically want to include these at the end of your Ajax functions in WordPress for the sake of making the return as fast as possible, and to make sure that no weird noise leaks into the response your JavaScript is expecting and working with.

AJAX in WordPress has a Million Possibilities

Hopefully you know understand all the basic dynamics of Ajax in WordPress: that Ajax allows your users to have a smoother experience than they can with simple PHP and HTML, and that it involves both traditional WordPress server-side code, and client-side JavaScript. I also sincerely hope that next time you’re reading a plugin, you’re able to spot the Ajax going on as soon as you see a add_action('wp_ajax... and aren’t left scratching your head as I was.

Our example has been pretty silly really, let’s admit. While there may be some value in knowing the server time in your JavaScript, the actual things you can use Ajax for are nearly unlimited. When you fully understand the power and potential of Ajax in WordPress, you can easily fetch any data you want from your WordPress site and use it in your front-end code without making the page refresh. (Another superpower: you can telegraph any data from the user into WordPress — but do be careful about logged-in state when doing so.) Your imagination is your only limit really. Happy hacking!

Image credit: shootingbrooklyn, Jean L

Most Voted
Newest Oldest
Inline Feedbacks
View all comments
June 19, 2016 2:35 am

Thank you for the article, made the ajax – wordpress stuff much clearer 🙂

June 21, 2016 12:11 pm
Reply to  surja


Polishing the WordPress Customizer Experience | WPShout
August 4, 2015 11:32 am

[…] they’re a small and unnecessary problem, because postMessage is available. postMessage uses AJAX to update customizer options previews on-the-fly, without page reload flickers and delays. The […]

Why the WordPress Front-End Editor is Going to be Amazing | WPShout.com
December 16, 2014 9:56 pm

[…] of the experience is the Ajax-based saving—another enormous selling point over TinyMCE. As we’ve covered, Ajax generally means that you can change data with no need for page refreshes: you can add and […]

Understanding the JSON API, XML-RPC, and Remote Publishing to Your WordPress Blog | WPShout.com
September 16, 2014 4:34 pm

[…] see references to around the WordPress world. We also mentioned XML very briefly recently in our discussion of Ajax in WordPress, because while it’s not (always or even mostly) the case that XML is the data-interchange […]