Adding Ajax to Your WordPress Plugin

Share this article

Using Ajax in your WordPress website is easier than you think. With jQuery on your side, you can submit data, as well as receive data. Communicating with WordPress is performed through a special Ajax dedicated WordPress action that is capable of handling the server side aspect of it.

WordPress and Ajax

Ajax occurs usually after a form submission, or by pressing a button, enabling you to send bits of data to the server in order to be processed. As an example, please consider the following snippet of code:

var data {
	action: 'spyr_plugin_do_ajax_request',
	var1: 'value 1',
	var2: 'value 2'

Using our friend jQuery, we are going to POST this to the server and get a server response. In WordPress, all Ajax requests are sent to admin-ajax.php for processing. This file resides within the /wp-admin directory of your WordPress site. Even though the file resides in the admin area of your site, you can use it to process interactions from the front-end, as well as the back-end.

The Action Parameter

In our previous example, the action parameter spyr_plugin_do_ajax_request is responsible for making the connection between the JavaScript file and the PHP code. It’s recommended to prefix all action, including this one; so that it is unique and identifiable. Make it look like it belongs to your WordPress plugin.

WordPress’ Dedicated Ajax Actions

There are two WordPress dedicated Ajax actions that we can use.

The first is wp_ajax_$action which handles the Ajax request if the user is logged in.

The second is wp_ajax_nopriv_$action which handles the Ajax request if the user is not logged in and has no privileges at all.

Following our previous examples, we would add these action hooks to our plugin like so:

add_action( 'wp_ajax_spyr_plugin_do_ajax_request', 'spyr_plugin_do_ajax_request' );
add_action( 'wp_ajax_nopriv_spyr_plugin_do_ajax_request', 'spyr_plugin_do_ajax_request' );

Now that we know the basics of how an Ajax event interacts with WordPress, let’s see a real world example. Let’s build a simple plugin which will allow administrators to delete a certain post from the front-end.

Ajax Post Delete Plugin

We can now start building a sample plugin, which will delete Posts via Ajax. Since this article is meant to introduce you to the inner-workings of processing an Ajax request, I feel this plugin will allow you to get your hands dirty without adding any type of confusion. Our plugin will consist of:

  • Adding the JavaScript file with the Ajax script
  • Adding a link to every post that when clicked, it will delete the post
  • Handling the Ajax request with PHP
  • Handling the button click with jQuery
  • Enqueuing our script
// Add script on single post only, if user has Admin rights
add_action( 'template_redirect', 'spyr_add_js_single_posts' );
function spyr_add_js_single_posts() {
	// We only want to add the script if is_single()
	// and can manage options (Admins)
	if( is_single() && current_user_can( 'manage_options' ) ) {

		// Get the Path to this plugin's folder
		$path = plugin_dir_url( __FILE__ );

		// Enqueue our script
		wp_enqueue_script( 'spyr_ajax_delete_posts', 
							$path. 'js/ajax-delete-posts.js',
							array( 'jquery' ),
							'1.0.0', true );

		// Get the protocol of the current page
		$protocol = isset( $_SERVER['HTTPS'] ) ? 'https://' : 'http://';

		// Set the ajaxurl Parameter which will be output right before
		// our ajax-delete-posts.js file so we can use ajaxurl
		$params = array(
			// Get the url to the admin-ajax.php file using admin_url()
			'ajaxurl' => admin_url( 'admin-ajax.php', $protocol ),
		// Print the script to our page
		wp_localize_script( 'spyr_ajax_delete_posts', 'spyr_params', $params );

Security is always important. So, we need to check whether the current user has sufficient permissions to see the ‘Delete’ link or not. We also need to ensure that we are viewing a single post, otherwise there is no point adding the ‘Delete’ link.

If both conditions are true, proceed enqueuing the script that contains the JavaScript code to handle what happens when the link is clicked. Pay close attention to how the protocol is being used in the front-end of the website. We must do this because of the same origin policy that Ajax requests and responses are subjected to. All Ajax requests and responses have to be processed from the same domain; and the protocols must match too.

In WordPress, it is possible to force the https protocol in the admin section of your site by setting ‘FORCESSLADMIN’ to ‘true’ in your WordPress configuration file. Sending a request from to won’t work. Even if we are forcing https:// on the back-end, we can make the call to admin-ajax.php without https://.

Finally, the last meaningful line in the code outputs our dynamic variables for us to use in ajax-delete-posts.js.

<script type='text/javascript'>
/* <![CDATA[ */
var spyr_params = {"ajaxurl":"http:\/\/\/wp-admin\/admin-ajax.php"};
/* ]]> */

Add Delete Link to Content

// Add an admin link to each post
add_filter( 'the_content', 'spyr_add_content_delete_link' );
function spyr_add_content_delete_link( $content ) {
	if( is_single() && current_user_can( 'manage_options' ) ) {
		// Get current post
		global $post;

		// Create a nonce for this action
		$nonce = wp_create_nonce( 'spyr_adp-delete-' . $post->ID );
		// Get link to adminn page to trash the post and add nonces to it
		$link = '<a href="'. admin_url( 'post.php?post='. $post->ID .'&action=trash&nonce=' .$nonce ) .'" 
				class="spyr_adp_link" data-nonce="'. $nonce .'" data-id="'. $post->ID .'">Delete Post</a>';

		// Append link to content
		return $content . '<p>'. $link .'</p>';

Short and simple. Check for permissions again, and make sure you are viewing a single post. These security measures are necessary and it’s something you are going to have to get used to. Next, create your nonce and tie it to an action; note the the special format. It uses the following structure, prefix_plugin-action-identifier, where spyr is the prefix, adp = Ajax Delete Post, delete is our action, and the post ID is the identifier. This is not necessary but it’s recommended when writing plugins. Note that we are also adding the Post’s ID and nonce value to the link using HTML5 data attributes. The last step is to attach your formatted link to the content.

Handling the Ajax Request with PHP and WordPress

We are now half way through the article. What follows is the code that actually handles the submission of your Ajax Request. Pay close attention since it relies on how you name the data submitted by the jQuery request to get the post ID (pid) and nonce value.

// Ajax Handler
add_action( 'wp_ajax_spyr_adp_ajax_delete_post', 'spyr_adp_ajax_delete_post' );
function spyr_adp_ajax_delete_post() {
	// Get the Post ID from the URL
	$pid = $_REQUEST['pid'];

	// Instantiate WP_Ajax_Response
	$response = new WP_Ajax_Response;

	// Proceed, again we are checking for permissions
	if( current_user_can( 'manage_options' ) && 
		// Verify Nonces
		wp_verify_nonce( $_REQUEST['nonce'], 'spyr_adp-delete-' . $pid ) &&
		// Delete the post
		wp_delete_post( $pid ) ) {
		// Build the response if successful
		$response->add( array(
			'data'	=> 'success',
			'supplemental' => array(
				'pid' => $pid,
				'message' => 'This post has been deleted',
		) );
	} else {
		// Build the response if an error occurred
		$response->add( array(
			'data'	=> 'error',
			'supplemental' => array(
				'pid' => $pid,
				'message' => 'Error deleting this post ('. $pid .')',
		) );
	// Whatever the outcome, send the Response back

	// Always exit when doing Ajax

spyr_adp_ajax_delete_post is the name of the action being passed on from the request of your JavaScript file. With this in mind, the full name for your action would be wp_ajax_spyr_adp_ajax_delete_post. The Post ID and nonce values are also passed on via the JavaScript file, and we can get them from $_REQUEST.

We are going to be instantiating WP_Ajax_Response which will allow us to return a nice XML response. You can then read and act upon what’s returned via jQuery. Once again, you need to verify that the user is an Administrator, and try to match nonce values before deleting the post. You need to build different Responses for each scenario so that you know for sure if the Post was deleted or not. You can then attach a brief and concise message describing the result so that you can provide extra feedback to the user. Finally, you send the Response back to the browser and exit. Always remember to exit when you are doing Ajax Requests.

The Request, as it will be sent to the server for processing, is as simple as this:


An example of the formatted XML file returned in the Response can be explored below:

	<response action="spyr_adp_ajax_delete_post_0">
		<object id="0" position="1">
				<message>This post has been deleted</message>

Handling the Button Click with jQuery

The only thing left to do now is write the JavaScript code, which will send the request and parse the response. The code itself is pretty self explanatory but I’ve gone ahead and added inline comments to make it easier to understand.

jQuery( document ).ready( function() {
	jQuery( '.spyr_adp_link' ).click( function( e ) {
		var link = this;
		var id   = jQuery( link ).attr( 'data-id' );
		var nonce = jQuery( link ).attr( 'data-nonce' );

		// This is what we are sending the server
		var data = {
			action: 'spyr_adp_ajax_delete_post',
			pid: id,
			nonce: nonce
		// Change the anchor text of the link
		// To provide the user some immediate feedback
		jQuery( link ).text( 'Trying to delete post' );

		// Post to the server spyr_params.ajaxurl, data, function( data ) {
			// Parse the XML response with jQuery
			// Get the Status
			var status = jQuery( data ).find( 'response_data' ).text();
			// Get the Message
			var message = jQuery( data ).find( 'supplemental message' ).text();
			// If we are successful, add the success message and remove the link
			if( status == 'success' ) {
				jQuery( link ).parent().after( '<p><strong>' + message + '</strong></p>').remove();
			} else {
				// An error occurred, alert an error message
				alert( message );
		// Prevent the default behavior for the link

Parsing the XML with jQuery is straightforward using jQuery.find(); look through the XML for an element as if you were trying to find an element in an HTML document.


As you can see, performing Ajax requests in your plugins and themes is a very straightforward process in WordPress. This is notably easier to achieve, thanks to the two dedicated actions: wp_ajax_$action and wp_ajax_nopriv_$action. This is just the beginning of a path of awesome code writing that will save page re-loads and add interactivity to your WordPress theme or plugin. What will you do next?

If you’re looking for more information on this topic, make sure you check out the WordPress Codex page on Ajax and Ajax in Plugins.

Frequently Asked Questions (FAQs) on Adding AJAX to Your WordPress Plugin

What is the role of AJAX in WordPress plugins?

AJAX, which stands for Asynchronous JavaScript and XML, plays a crucial role in WordPress plugins. It allows for the execution of complex actions on the website without needing to reload the entire page. This enhances the user experience by making the website more responsive and interactive. AJAX is used in various functionalities such as form submissions, loading more posts, and live searches.

How do I add AJAX to my WordPress plugin?

Adding AJAX to your WordPress plugin involves a few steps. First, you need to enqueue your JavaScript file using the wp_enqueue_script function. Then, you need to localize the script using the wp_localize_script function. This allows you to pass data from PHP to JavaScript. Finally, you need to add an action hook that will handle the AJAX request on the server side.

How do I handle AJAX requests in WordPress?

AJAX requests in WordPress are handled using action hooks. You need to add an action hook that corresponds to the action parameter in your AJAX request. This hook will trigger a function that processes the request. The function should end with a call to wp_die() to ensure that the AJAX process is properly terminated.

Why is my AJAX request returning a 0?

If your AJAX request is returning a 0, it means that the request is not being processed correctly. This could be due to several reasons. One common reason is that the action hook for handling the AJAX request is not correctly set up. Make sure that the action parameter in your AJAX request matches the action hook in your PHP code.

How can I debug AJAX in WordPress?

Debugging AJAX in WordPress can be done using various methods. One common method is to use the browser’s developer tools. You can inspect the network tab to see the AJAX requests and responses. Another method is to use the WP_DEBUG and WP_DEBUG_LOG constants in your wp-config.php file. This will log any errors in a debug.log file in your wp-content directory.

Can I use AJAX in WordPress without a plugin?

Yes, you can use AJAX in WordPress without a plugin. You can add AJAX functionality directly to your theme’s functions.php file. However, it’s generally recommended to use a plugin for this purpose to keep your theme’s code clean and maintainable.

How do I use the wp_ajax_ and wp_ajax_nopriv_ hooks?

The wp_ajax_ and wp_ajax_nopriv_ hooks are used to handle AJAX requests in WordPress. The wp_ajax_ hook is used for logged-in users, while the wp_ajax_nopriv_ hook is used for non-logged-in users. You add these hooks in your PHP code and associate them with a function that processes the AJAX request.

How do I pass data from JavaScript to PHP in WordPress AJAX?

Data is passed from JavaScript to PHP in WordPress AJAX using the wp_localize_script function. This function allows you to pass an array of data to your JavaScript file. The data can then be accessed in your AJAX request.

How do I use nonce in WordPress AJAX?

Nonces are used in WordPress AJAX to ensure the security of your AJAX requests. You can generate a nonce using the wp_create_nonce function and pass it to your JavaScript file using the wp_localize_script function. Then, you can include the nonce in your AJAX request. On the server side, you can verify the nonce using the check_ajax_referer function.

How do I handle AJAX errors in WordPress?

AJAX errors in WordPress can be handled using the .fail() method in your AJAX request. This method is triggered when the AJAX request fails. You can use this method to display an error message or perform other actions when an error occurs.

Yojance RabeloYojance Rabelo
View Author

Yojance Rabelo has been using WordPress to build all kinds of Websites since July 2006. In his free time he likes to try out new technologies, mainly PHP and JavaScript based, and also playing with his EV3RSTORM, a Lego MINDSTORMS robot. He maintains his own blog among other sites about various topics.

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week
Loading form