WordPress AJAX: Frontend & Backend Implementation

I was recently working on a WP site that required AJAX functionality on the frontend. Having implemented WordPress AJAX for my Book It! Transportation plugin on the backend, I figured it would be a cinch. Come to find out, it required a little more work to accomplish.

AJAX in a WordPress plugin or theme is a cinch — but there are a few nuances you should be aware of when working with WordPress AJAX.

There’s numerous ways to implement AJAX in WordPress, but there’s only one WordPress way. In this article, I’ll go over the method WordPress supports, is future-proof, logical and provides numerous options out of the box — using wp_ajax_my_action & wp_ajax_nopriv_my_action. WordPress AJAX, the quick and dirty:

WordPress AJAX in the Backend

add_action( 'admin_footer', 'my_action_javascript' );
function my_action_javascript() {
  $ajax_nonce = wp_create_nonce( "my-special-string" );
  ?>
  <script>
  jQuery( document ).ready( function( $ ) {
    var data = {
      action: 'my_action',
      security: '<?php echo $ajax_nonce; ?>'
    };

    $.post( ajaxurl, data, function( response ) {
      alert( 'Response: ' + response );
    });
  });
  </script>
<?php 
}

add_action( 'wp_ajax_my_action', 'my_action_callback' );
function my_action_callback() {
  check_ajax_referer( 'my-special-string', 'security' );
  echo 'It worked!';
  die();
}

WordPress AJAX in the Frontend

add_action( 'wp_enqueue_scripts', 'my_scripts' );
function my_scripts() {
  wp_enqueue_script( 'script-name', get_template_directory_uri() . '/js/example.js', array('jquery'), '1.0.0', true );
  wp_localize_script( 'script-name', 'MyAjax', array(
    'ajaxurl' => admin_url( 'admin-ajax.php' ),
    'security' => wp_create_nonce( 'my-special-string' )
  ));
}

add_action( 'wp_ajax_my_action', 'my_action_callback' );
add_action( 'wp_ajax_nopriv_my_action', 'my_action_callback' );
function my_action_callback() {
  check_ajax_referer( 'my-special-string', 'security' );
  echo 'It worked!';
  die();
}

# WordPress AJAX for the Backend

This is a cinch to do. Currently, the core of WordPress uses AJAX only in the administration screens. For instance, AJAX is used for instant updates when you are doing comment moderation, and when you are adding and deleting items from lists such as categories, blogroll, and posts; AJAX is also the technology behind the auto-save functionality on post and page editing screens. Several themes and plugins also use AJAX; for instance, some post rating plugins use AJAX to store the visitor’s rating in the database and then display an updated average rating.

Since AJAX is already built into the core WordPress administration screens, adding more administration-side AJAX functionality to your plugin or theme is fairly straightforward, check out the example below.

add_action( 'admin_footer', 'my_action_javascript' );
function my_action_javascript() {
  //Set Your Nonce
  $ajax_nonce = wp_create_nonce( "my-special-string" );
  ?>
  <script>
  jQuery( document ).ready( function( $ ) {
    var data = {
      action: 'my_action',
      security: '<?php echo $ajax_nonce; ?>',
      whatever: 1234
    };
    // Since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
    $.post( ajaxurl, data, function( response ) {
      alert( 'Got this from the server: ' + response );
    });
  });
  </script>
<?php } ?>

This should be fairly straight forwared. It uses WP’s admin_footer action (see add_action) to include some JS in the footer that makes the AJAX magic happen. Take a look at $.post if you’re not familiar with it.

With the code above, you’re defining your action, a WordPress nonce for security, and any other data you want to send. You’ll use the action you define as part of the WP function you’ll create that handles the AJAX request. See below:

add_action( 'wp_ajax_my_action', 'my_action_callback' );
function my_action_callback() {
  global $wpdb; // this is how you get access to the database
  check_ajax_referer( 'my-special-string', 'security' );
  $whatever = intval( $_POST['whatever'] );
  $whatever += 10;
  echo $whatever;
  die(); // this is required to return a proper result
}

We’re using WP’s wp_ajax_(action) hook to handle the AJAX request. This hook allows you to create custom handlers for your own custom AJAX requests. The wp_ajax_ hook follows the format “wp_ajax_$youraction”, where $youraction is your AJAX request’s ‘action’ property you sent in the JS above.

Also, be sure to include the check_ajax_referer to verify that the request came from the right place.

That’s it! You will need to add a few details, such as error checking, but hopefully the example above will be enough to get you started on your own administration-side AJAX plugin.

WordPress AJAX Backend Example

Here’s a full working example of WordPress AJAX in the backend. This will produce a JS alert box with the text 1044 when a page has been loaded in the administration panel. In the functions.php file:

// The JavaScript
function my_action_javascript() {
  //Set Your Nonce
  $ajax_nonce = wp_create_nonce( 'my-special-string' );
  ?>
  <script>
  jQuery( document ).ready( function( $ ) {
    var data = {
      action: 'my_action',
      security: '<?php echo $ajax_nonce; ?>',
      whatever: 1234
    };
    // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
    $.post( ajaxurl, data, function( response)  {
      alert( 'Got this from the server: ' + response );
    });
  });
  </script>
  <?php
}
add_action( 'admin_footer', 'my_action_javascript' );
// The function that handles the AJAX request
function my_action_callback() {
  global $wpdb; // this is how you get access to the database
  check_ajax_referer( 'my-special-string', 'security' );
  $whatever = intval( $_POST['whatever'] );
  $whatever += 10;
  echo $whatever;
  die(); // this is required to return a proper result
}
add_action( 'wp_ajax_my_action', 'my_action_callback' );

# WordPress AJAX for the Frontend

This takes a little extra work to accomplish. Since WordPress 2.8, there is a hook similar to wp_ajax_(action):

You’ll need to use this hook if you’re planning on implementing WordPress AJAX on the frontend. If you want to fire your AJAX function both both logged-in and logged-out users, you’d do this:

add_action( 'wp_ajax_my_action', 'my_action_callback' );
add_action( 'wp_ajax_nopriv_my_action', 'my_action_callback' );

Something else to keep in mind when implementing WordPres AJAX on the frontend is, unlike on the admin side, the ajaxurl javascript global does not get automatically defined for you, unless you have BuddyPress or another Ajax-reliant plugin installed. So instead of relying on a global javascript variable, you’ll need to declare a javascript namespace object with its own property, ajaxurl. Use wp_localize_script() to make the URL available to your script, and generate it using this expression: admin_url( 'admin-ajax.php' ). See below:

wp_localize_script( 'script_handle', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php')));

Another thing to keep in mind is, both front-end and back-end AJAX requests use admin-ajax.php so is_admin() will always return true in your action handling code. When selectively loading your AJAX script handlers for the frontend and backend, and using the is_admin() function, your wp_ajax_(action) and wp_ajax_nopriv_(action) hooks MUST be inside the is_admin() === true part.

AJAX requests bound to either wp_ajax_ or wp_ajax_nopriv_ actions are executed in the WP Admin context. Carefully review the actions you are performing in your code since unprivileged users or visitors will be able to trigger requests with elevated permissions that they may not be authorized for. See below:

if ( is_admin() ) {
    add_action( 'wp_ajax_my_frontend_action', 'my_frontend_action_callback' );
    add_action( 'wp_ajax_nopriv_my_frontend_action', 'my_frontend_action_callback' );
    add_action( 'wp_ajax_my_backend_action', 'my_backend_action_callback' );
    // Add other back-end action hooks here
} else {
    // Add non-Ajax front-end action hooks here
}

Here the AJAX action my_frontend_action will trigger the PHP function my_frontend_action_callback() for all users. The AJAX action my_backend_action will trigger the PHP function my_backend_action_callback() for logged-in users only.

WordPress AJAX Frontend Example

Here’s a full working example of WordPress AJAX in the frontend. This will produce a JS alert box with the text 1044 when a page has been loaded in the administration panel. In the functions.php file:

// Add the JS
function theme_name_scripts() {
  wp_enqueue_script( 'script-name', get_template_directory_uri() . '/js/example.js', array('jquery'), '1.0.0', true );
  wp_localize_script( 'script-name', 'MyAjax', array(
    // URL to wp-admin/admin-ajax.php to process the request
    'ajaxurl' => admin_url( 'admin-ajax.php' ),
    // generate a nonce with a unique ID "myajax-post-comment-nonce"
    // so that you can check it later when an AJAX request is sent
    'security' => wp_create_nonce( 'my-special-string' )
  ));
}
add_action( 'wp_enqueue_scripts', 'theme_name_scripts' );
// The function that handles the AJAX request
function my_action_callback() {
  check_ajax_referer( 'my-special-string', 'security' );
  $whatever = intval( $_POST['whatever'] );
  $whatever += 10;
  echo $whatever;
  die(); // this is required to return a proper result
}
add_action( 'wp_ajax_my_action', 'my_action_callback' );

In the example.js file:

jQuery(document).ready(function($) {

  var data = {
    action: 'my_action',
    security : MyAjax.security,
    whatever: 1234
  };

  // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
  $.post(MyAjax.ajaxurl, data, function(response) {
    alert('Got this from the server: ' + response);
  });
});

Learn more about WordPress AJAX

Comments

  1. this is the best one I have read and working perfectly..Thanks a ton

  2. Like the other comments, i want to tank you for this excellent explanation!!

    I’ve also created several ajax calls on the admin side in the past, and needed a front-end solution for my current project.

    I have one tiny tiny thing.
    The result in the alert box will be 1244 not 1044 haha ^^

    Keep up the good work!

  3. Mohammad Kazem Hassani May 16, 2017

    thanks really best tutorial about If you want to fire your AJAX function both both logged-in and logged-out users, you’d do this:
    add_action( ‘wp_ajax_my_action’, ‘my_action_callback’ );
    add_action( ‘wp_ajax_nopriv_my_action’, ‘my_action_callback’ );

    I have searched very much here i found best answer.

  4. Dude, that is the best, if not the only, blog post about Ajax in WordPress that is good.
    I was strugling for hours to understand what was wrong on my code. Thank you for sharing it.

  5. Thanks for your article, its give me some insights 😀

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

All comments are held for moderation and only published when on topic and not rude. You'll even get little stars if you do an extra good job.

You may write comments in Markdown. This is the best way to post any code, inline like `<div>this</div>` or multiline blocks within triple backtick fences (```) with double new lines before and after.

Want to tell me something privately, like pointing out a typo or stuff like that? Contact Me.

icon-search icon-link