Using AJAX With PHP on Your WordPress Site Without a Plugin

Ajax is damn cool! It enables websites to load content into various elements without refreshing the page. This may not seem like a huge feature list but it allows us to do so much.

From up-voting to liking, from Disqus to Tweets, all these actions use Ajax to give you a seamless user experience.

It was made popular in 2005 by Google in their suggest feature, which gives you search suggestions as you type. This is not only a seamless experience but would be completely impossible without AJAX.

In this article I’ll show you how to use Ajax in WordPress. It is a little more complicated than you may be used to, for good reason, but if you have a good understanding of HTML, CSS and PHP, and rudimentary understanding of Javascript, you should be just fine. Let’s get started.

Note: While this post provides a great guide to getting started with AJAX, if you want to level up your development skills why not check out The Academy? There are courses on everything from WordPress development and learning PHP to starting an online business and mastering Multisite. And if you’re an WPMU DEV member, joining The Academy is free!

How AJAX Works

Ajax is actually just Javascript. It is short for Asynchronous Javascript And XML. The reason it can quickly become a lot more complex is that it is a technology meant as a bridge between your website and your server. This means that you will use it in conjunction with the rest of your Javascript code, your CSS, HTML and perhaps even PHP.

The heart of Ajax is the XMLHttpRequest object, which exchanges data with the server. The whole process works a lot like submitting a form. Here are the basic steps:

  1. You specify information to send
  2. You configure the Ajax call
  3. The XMLHttpRequest object is used to send the data to the server
  4. The server response is returned and can be used by your JS code

Ajax is most commonly used through jQuery wrapper functions. If you would like to learn Ajax without jQuery I suggest taking a look at the W3Schools Tutorial. Here we’ll be looking at the jQuery functions only.

Your First Ajax Call

Before we jump in, you will need a theme you can modify – a child theme or a plugin. I recommend a plugin and creating one is super-simple. In a nutshell: create a folder in the wp-content/plugins directory, I named mine ajax-text. Within your folder create a PHP file with the same name as the folder – mine is ajax-test.php. Paste the following code into this file:

Once saved you should see your plugin pop up in the plugins section of the backend of your WordPress site. Go ahead and activate it. If you would like to know a whole lot more about creating plugins in general, take a look at our plugin development guide.

Enqueueing Our JavaScript

We’ll need to add a JavaScript file to our plugin, which we’ll do by enqueueing it. This is easy to understand and simple to copy-paste but if you want to know more we have a guide on enqueueing, too.

The code above adds a test.js script to our site. I’ve indicated that jQuery is a dependency and that it should be loaded in the footer. Now let’s go in and create a simple Ajax call within the Javascript file.

Creating the Ajax Call

An Ajax call has a lot of parameters we can set. Take a look at all the available options on the jQuery Documentation page. We’ll stick with the basics here:

All we’re doing is using the $.ajax() function and specifying some options. The url tells the Ajax call where to send the request. The success parameter is a function which receives the response in the first parameter.

The URL should point to your actual main page. If all is well, as soon as you reload the page you will receive a popup telling you how many div elements you have on the page.

Alert box
Alert box

This looks quite ugly but what we’ve done is actually loaded a completely separate page without re-loading the one we were on.

A Complete WordPress Ajax Example

WordPress does a lot more to help you with Ajax calls and to standardize how they are performed. Let’s replace that URL with something more dynamic and create a better way to interact with the server. In this example we’ll take a look at how we can create a “Love this post” function on your site.

I started a new plugin named “post-love” – I’ll have a zip file ready for you guys and it contains the whole plugin. You can download it at the end of the article.

Storing And Displaying Our Data

We’ll be storing the number of “loves” a post has received in a meta field in the database, let’s call it post_love. The value of this field will be displayed under each post in the single page, here’s how:

By using the the_content filter we can display anything we’d like, right under the post content. I made sure to only do this on single pages using the is_single() conditional function. I retrieved the love count from the post meta and made sure the value was 0 if no love has been given yet.

I then used some HTML to create the display which consists of a link to give love and a span for showing the count. I also added the ID of the post as a data parameter to the link. This will be used later. I then returned the content followed by our text.

It looks very basic, so let’s give it a little style by enqueueing a stylesheet and adding some styles. First the enqueue:

Note that I use the is_single() conditional tag here as well. There’s no sense in loading our stylesheet on any other page since it won’t be used. This enables us to minimize the effect of our plugin on the site’s loading time. Create the love.css file in the plugin directory and use the following CSS to give it some style.

The end result should be a nice button with a 3D effect and a counter next to it, like you see below.

Our little love button
Our little love button

The Ajax Call

Next, let’s assemble the Ajax call. This involves enqueueing our script and writing the Javascript. Before do that, let’s discuss the url parameter of the Ajax call. In our last example I hard-coded the url. We can’t do that in a proper plugin or theme because everyone has a different site URL.

Luckily WordPress is here to help. It gives us a unified file to use – wp-admin/admin-ajax.php and the means to grab the full URL of the file. It involves a little trick while enqueueing, here’s how it’s done:

As you can see, I registered the JavaScript file as usual. Then I used the wp_localize_script() function to pass a string to our script. This function was originally meant to add translation support to Javascript files – you can add as many strings as you like in that array. In our script we’ll be able to use postlove.ajax_url to output the URL of the admin-ajax.php file, let’s do that now.

This isn’t the final version just yet but communicates with the server just fine. First of all, we execute a function whenever we click on a “give love” button. We grab the ID of the current post and store it in the post_id variable.

Next we build an Ajax call. The URL uses the postlove.ajax_url discussed above. I set the type to post which is the equivalent of setting a form to the same value. If you use “post” you can retrieve the data sent via $_POST, if you use “get” you can grab it with $_GET.

The data section holds any parameters you want to send yourself. We need to send the post ID so we know which post to attribute the love to. WordPress also requires us to send an action when using the admin-ajax.php file. Keep in mind that we’ve set this to ‘post_love_add_love’. Finally, we simply alert the response in the success function.

If you try it out now the alert will show 0 which is perfectly fine, it actually means all is well! If an action hook is not defined for our set action (we’ll do this in the next step) the admin-ajax file exists and returns 0 – which is what is happening.

Server Side Processing

At this stage we are sending things to the server but we need to tell the server what to do with our data. We should increment the love counter meta box by one and return the new value. To create a facility for processing data arriving via AJAX we’ll need to use two hooks:

The first hook is executed for guest users, the second for logged in users. This is a great way to control access by the way! The convention is this:

Remember how we defined an action parameter in our Ajax call? This needs to be appended to wp_ajax_ and/or wp_ajax_nopriv_. The function can be named anything, I just used the same string as the action name for consistency. Let’s move on and create the incrementing functionality.

Nothing special going on here. The current value is retrieved, incremented and saved. We echo the value, this will be the response. The only thing to note is that you must use die() at the end. If you don’t, admin-ajax.php will execute it’s own die(0) code, echoing an additional zero in your response.

If you press the button now you should see the new love value being alerted. Reload the page and the button should reflect it as well. Functionality-wise we are nearly there, we just need to make sure the count changes without needing to reload the page. From here on out this is easy JS, here’s the full Ajax call with the count change built in:

With that final bit added the button now shows the correct count after it is clicked, we’re all done. Or are we?

Graceful Fallback

Making our element a link is not very semantic of us since it isn’t actually a link. The reason I decided to do so is that if someone doesn’t have Ajax enabled, why not make this link work all the same? We need to modify things slightly but not a lot:

First of all, we need to do is make the target URL the same as the target of our Ajax call: Here’s what the final version looks like:

Since our URL is now not # we need to return false at the end of our click event to make sure the URL isn’t followed for users who have Javascript enabled.

The final step is to differentiate between Ajax and non-Ajax operations in our post_love_add_love() function. When Ajax is used the new value needs to be echoed, the script needs to die. When Ajax is not used (ie: the user is redirected to admin-ajax) we need to simply redirect back to the article after we run our script. Here’s the final version of our post_love_add_love() function:

I’ve changed the $_POST variables to $_REQUEST since Ajax users will use post while others will use get. The $_REQUEST variables allows access to our data whichever the case.

With that you’ve completed this tutorial, you now have a great button to get some love for your posts. In the conclusion I’ll share the download link for the full plugin I’ve created.

There’s More To Do!

As I mentioned, Ajax isn’t hard but there are a lot of simple things you need to know. Here are the two most important aspects of using Ajax once you have the basics down:


Security can be a big issue with Ajax if you’re not careful. Our button doesn’t check for multiple clicks so you could just sit there clicking it and incrementing the value all day. Aside from skewing results it could result in a higher server load, especially if a couple of people do it at once.

In addition, you wouldn’t even have to click the button. Just by visiting you could increment the counter.

While our button could only cause minimal harm, some plugins allow you to delete posts from the front-end. What if there was a URL you could visit to accomplish the same thing? Not an idea situation.

One way to prevent these security holes from opening up is to use nonces. Nonces are a way of securing forms and links from malicious attempts.

User Interface and Experience

Another important aspect of Ajax is user experience. The whole premise of the technology is that the user gets more interactivity and less loading time. This also means that you need to put a lot of work into your Ajax functionality to make sure they really do improve the experience.

Users should always know what is happening and why. If I were creating this plugin for the repository the first thing I would do is add a loading state, during which it is impossible to press the button. The beforeSend parameter of the $.ajax() function allows us to execute some code before the data is sent to the server.

In this function I would add the loading state and disable the button. Upon success the button would pop back to its normal state and be usable once again.

It may also be advisable to add some sort of visual cue to the number change. If the user doesn’t know what to expect, they may not notice what’s changed. A little shake or a highlight could do the trick.

Be very careful not to gravitate toward the other extreme. With the advent of Ajax and animation techniques people tended to make everything move, animate and do unnecessary things. Never make your users wait for the animation to end and only add JS eye-candy where it makes sense, otherwise the user experience will be lowered, not raised.


Ajax is a powerful tool in a developers tool belt to add interactivity and to lower server strain. It opens countless doors, such as allowing your comments to appear without reloading, infinite scrolling for posts, lazy-loading images, and so much more.

As long as you use it where necessary and take the time to round off your Ajax calls with some UI details, Ajax will make your applications that much better.

If you’d like to see the plugin as a whole you are welcome to download it, learn a little something from it and also use it on your website.

Do you use Ajax on your site? Let us know in the comments below.