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)
:
wp_ajax_nopriv_(action)
executes for users that are not logged in.
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
- WordPress Codex AJAX
- WordPress Codex AJAX in Plugins
- WordPress AJAX Login Without a Plugin – The Right Way by Natko Hasic
- Delete A WordPress Post Using AJAX by Daniel Pataki
- How to Use AJAX With PHP on Your WordPress Site Without a Plugin by David Albert
- Getting Started with AJAX & WordPress Pagination by Soumitra Chakraborty
7 comments on “WordPress AJAX: Frontend & Backend Implementation”.
# 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.
# Aug 22, 2019
this is the best one I have read and working perfectly..Thanks a ton
# 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!
# 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.
# Sep 14, 2014
Thanks for your article, its give me some insights 😀
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.