WordPress AJAX: Frontend & Backend Implementation

Though there are a number of ways to use WordPress AJAX, there's one logical, future-proof & feature-rich method you should follow — the right way. Learn how to implement WordPress AJAX for both the frontend site & backend admin interface.
Published
Updated
Typical Read
9 minutes
Sponsored
Help support open-source projects & pro-bono non-profit services by donating today.
Find your next web developer job
jobs by Indeed

WordPress AJAX: Frontend & Backend Implementation was originally published on Jan 16, 2014 and has recently been updated on Aug 5, 2020 to reflect emerging trends.

AJAX is a beautiful thing for users. It allows real-time changes without the need for reloads. WordPress has this in core — and this article is all about how to implement WordPress AJAX the right way.

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 in the Administration Side

Since WordPress uses AJAX by default in admin, adding your own AJAX functionality is a cinch. All you need to do is use the functions it provides. Let’s look at an example:

<?php
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();
}

Check out the more in-depth explanation on how to implement AJAX on the administration side below.

WordPress AJAX on the Frontend

Adding AJAX on the frontend or viewer-facing side of your site via a theme or plugin requires a little extra snippet and just as easy to setup — the key a special action hook for non-logged in users. Let’s take a look how this is accomplished below.

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();
}

Check out the more in-depth explanation on how to setup AJAX on the frontend for themes or plugins below.

What is AJAX? AJAX stands for Asynchronous JavaScript And XML — a fancy term that basically mean it allows you to create dynamic applications that work in real-time, are interactive & responsive to user input. One of the most ubiquitous examples of AJAX is Google’s “Google Suggest” feature. You type, it starts searching & provides recommended queries in a dropdown after each keystroke — a beautifully simple & highly useful user experience.

Difference Between wp_ajax_ & wp_ajaxnopriv

wp_ajax_ is fired for users who are logged-in, while wp_ajax_nopriv_ is fired when users aren’t logged in. You can use both hooks for your function, but note that the hook will be fired once in a single request.

wp_ajax_(action)

This hook allows you to handle your custom AJAX endpoints. The wp_ajax_ hooks follows the format "wp_ajax_$youraction", where $youraction is the 'action' field submitted to admin-ajax.php.

wp_ajaxnopriv_(action)

This hook is functionally the same as wp_ajax_(action), except the “nopriv” variant is used for handling AJAX requests from unauthenticated users, i.e. when is_user_logged_in() returns false.

Unlike wp_ajax_(action) the ajaxurl javascript global property will not be automatically defined and must be included manually or by using wp_localize_script() with admin_url( 'admin-ajax.php' ) as the data.

Step-by-Step 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() {
  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:

// Complete working example of AJAX in admin
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
}

// The function that handles the AJAX request
add_action( 'wp_ajax_my_action', 'my_action_callback' );
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
}

Step-by-Step 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_action', 'my_action_callback' );
} 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
add_action( 'wp_enqueue_scripts', 'theme_name_scripts' );
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' )
  ));
}

// The function that handles the AJAX request
add_action( 'wp_ajax_my_action', 'my_action_callback' );
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
}

In the example.js file:

jQuery(document).ready(function($) {
  var data = {
    action: 'my_action',
    security : MyAjax.security,
    whatever: 1234
  };

  $.post(MyAjax.ajaxurl, data, function(response) {
    alert('Got this from the server: ' + response);
  });
});

How Not to Use AJAX

One of the biggest mistakes I see WordPress developers use when implementing WordPress AJAX is by including the wp-load.php file at the top of your script. Though this does give you access to WordPress function to detect the current user and so on, it’s basically a hack — a hack that’s no so future-proof. Plus, it’s much less secure and doesn’t give you some of the useful options that the WordPress system does.

Learn more about WordPress AJAX

Did you find WordPress AJAX: Frontend & Backend Implementation useful? Get articles in your inbox.

…and don’t worry, I hate spam as much as you. Expect to hear from me at most once a week.

Latest Job Postings
Posted on Aug 9, 2020 at 10:40pm
United States
Posted on Aug 9, 2020 at 9:17pm
Full-time
Los Angeles
Posted on Aug 9, 2020 at 9:15pm
Full-time
Los Angeles
jobs by Indeed
Sponsored
Do you have a great article to share you want to contribute? Contact me about your idea.
Sponsored
Do you have a great article to share you want to contribute? Contact me about your idea.
Sponsored
Do you have a great article to share you want to contribute? Contact me about your idea.
Sponsored
Need help with website, a boost in ranking or online marketing? Contact me today for a free quote.
Sponsored
Sponsor my site by donating to help support open-source projects, like WordPress Zero Spam, Referrer Analytics & others.

7 Comments on “WordPress AJAX: Frontend & Backend Implementation”

Matthe Harris

# Jan 15, 2020

One thing that is not clear to me is the use of the nonce.

– Does this need to be regenerated and passed down again somehow so that the form can be used repeatedly?
– Does it need a separate nonce variable passing for every form you want to process?

I suspect the answer to both of these is yes but I haven’t seen any of the ajax tutorials out there cover this that I’ve read so far.

# Mar 1, 2020

Yes & yes. Nonces aren’t required but add increased security to help avoid spam, blunt-force attacks, etc. See https://codex.wordpress.org/WordPress_Nonces for more info.

ram

# Aug 22, 2019

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

Bjorn

# Jul 14, 2017

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!

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.

# Jan 25, 2015

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.

Rafadev

# Sep 14, 2014

Thanks for your article, its give me some insights 😀

Leave a Reply

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

All comments posted on 'WordPress AJAX: Frontend & Backend Implementation' are held for moderation and only published when on topic and not rude. Get a gold star if you actually read & follow these rules.

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.