Going to show 2 ways of performing AJAX requests in wordpress.
I’ll be using jQuery for the sake of simplicity.
Using hooks
Let’s start off by adding jQuery and a custom javascript file to our page:
function my_enqueue($hook) {
wp_enqueue_script(
'my_jquery',
'https://code.jquery.com/jquery-3.5.0.min.js',
array(),
false,
true
);
wp_enqueue_script(
'my_script',
get_stylesheet_directory_uri() . '/assets/js/scripts.js',
array(),
false,
true
);
}
add_action('wp_enqueue_scripts', 'my_enqueue', 999999);
Now, the AJAX request will have to be done to the admin ajax url.
Here is one possible way of doing it:
function my_ajaxurl() {
echo '<script type="text/javascript">
var ajaxurl = "' . admin_url('admin-ajax.php') . '";
</script>';
}
add_action('wp_head', 'my_ajaxurl');
The code below should be added on the scripts.js file:
jQuery.ajax({
method: "POST",
url: ajaxurl,
data: {name: "John Doe", location: "Planet Earth", action: "ajaxTest"}
}).done(function(msg) {
console.log(msg);
});
Where name and location are the parameters we want to send to the function that is going to handle the request and the action is where the name of the function is defined.
Now the function:
function ajaxTest() {
echo $_POST['name'];
echo '<br>';
echo $_POST['location'];
echo '<br>';
wp_die();
}
Finally, we need to specify to actions in order to bind the AJAX request to the above function:
add_action('wp_ajax_ajaxTest', 'ajaxTest');
add_action('wp_ajax_nopriv_ajaxTest', 'ajaxTest');
wp_ajax_[action_name] fires authenticated Ajax actions for logged-in users.
The [action_name] will have to match the string defined on action param on the AJAX request – ajaxTest.
The second param of the do_action will have to match the function name – also ajaxTest.
wp_ajax_nopriv_[action_name] fires non-authenticated Ajax actions for logged-out users.
The [action_name] will have to match the string defined on action param on the AJAX request – ajaxTest.
The second param of the do_action will have to match the function name – also ajaxTest.
Here is the full code for the functions.php file:
function my_enqueue($hook) {
wp_enqueue_script(
'my_jquery',
'https://code.jquery.com/jquery-3.5.0.min.js',
array(),
false,
true
);
wp_enqueue_script(
'my_script',
get_stylesheet_directory_uri() . '/assets/js/scripts.js',
array(),
false,
true
);
}
add_action('wp_enqueue_scripts', 'my_enqueue', 999999);
function my_ajaxurl() {
echo '<script type="text/javascript">
var ajaxurl = "' . admin_url('admin-ajax.php') . '";
</script>';
}
add_action('wp_head', 'my_ajaxurl');
function ajaxTest() {
echo $_POST['name'];
echo '<br>';
echo $_POST['location'];
echo '<br>';
wp_die();
}
add_action('wp_ajax_ajaxTest', 'ajaxTest');
add_action('wp_ajax_nopriv_ajaxTest', 'ajaxTest');
Using REST API
This is a more straightforward way.
Also enqueue the same scripts:
function my_enqueue($hook) {
wp_enqueue_script(
'my_jquery',
'https://code.jquery.com/jquery-3.5.0.min.js',
array(),
false,
true
);
wp_enqueue_script(
'my_script',
get_stylesheet_directory_uri() . '/assets/js/scripts.js',
array(),
false,
true
);
}
add_action('wp_enqueue_scripts', 'my_enqueue', 999999);
And define a javascript variable with site url:
function my_ajaxurl() {
echo '<script type="text/javascript">
var site_url = "' . site_url() . '";
</script>';
}
add_action('wp_head', 'my_ajaxurl');
Now define your endpoint along with the handler function:
add_action('rest_api_init', function () {
register_rest_route('stuff/v1', '/test/', array(
'methods' => 'POST',
'callback' => 'test_endpoint'
));
});
function test_endpoint($request) {
$stuff = $request['stuff'];
return "Received " . esc_html($stuff);
}
Now, on the scripts.js file:
$.ajax( {
url: site_url + '/wp-json/stuff/v1/test',
method: 'POST',
data:{
'stuff' : 'Hello World!'
}
}).done( function (response) {
console.log(response);
});
And that’s it.
Reference:
https://developer.wordpress.org/reference/hooks/wp_ajax__requestaction/
https://developer.wordpress.org/reference/hooks/wp_ajax_nopriv__requestaction/
https://wordpress.stackexchange.com/a/339855/186121
https://wordpress.stackexchange.com/a/193818/186121