If you already know what is an AJAX request please just jump right to the section where I will talk about how to start coding.

What is an AJAX request

First you will need to understand that an AJAX request is nothing more then a simple GET or POST to an URL that you defined, you will pass some parameters and this URL should answer you with some other data that you will be able to parse on the JavaScript and using it you will be able to give your users the needed visual feedback.

So when you visit a URL like https://bordoni.me on your browser you are doing a GET request without any parameters, if you visit https://bordoni.me/?p=216 you will do a GET to this Post on WordPress by passing the p parameter on the URL then WordPress will redirect you to the correct link because permalinks are active.

A GET request is limited to a few parameters so that’s why it’s always better to use POST when dealing with AJAX, so that we don’t have to limit ourselves that much, the POST is limited by size, so we will only have a limit when we reach the MB scale.

See LimitRequestBody for Apache and client_max_body_size for NGINX.

WordPress backend

Each and every system has it’s own method of routing a request, in WordPress we send all the AJAX calls to a single URL, and then WordPress will route internally to the correct method based on a param that you will send along with your AJAX request.

First lets understand where we will call the WordPress backend and how to pass this variable (url) to the JavaScript side of our application.

Using the admin_url( 'admin-ajax.php' ) anywhere within our WordPress installation will return a string with the full URL to where we should do our AJAX request.

On my website the return would be https://bordoni.me/wp-admin/admin-ajax.php.

JavaScript actions

So that you can do the AJAX request you will need some JS action in here, what you need to is create a file which will be loaded on the page that you will fire the AJAX via some user interaction.

To enqueue a JavaScript file on your WordPress page you will need to referrer to wp_enqueue_script and wp_register_script, which will load a and register a script respectively.

The following script will allow you to do a simple AJAX request and print the output to the JavaScript browser console.

jQuery( document ).ready( ( $ ) => {
    // Information of our Request.
    const data = {
        action: 'bordoni_query_posts',
        post_type: 'post',
        qty: 15
    // The variable ajax_url should be the URL of the admin-ajax.php file.
    $.post( ajax_url, data, function(response) {
        console.log( response );
    }, 'json' );
} );

I’ve used jQuery.post to make our lives easier.

If you are not going to use JSON as your response, you might want to check the documentation on which other types of response are allowed.

WordPress AJAX action Callback

After you’ve set a JavaScript action, you will need to intercept this action via an action to be able to print out the response you want.

Your WordPress will read which action you’ve send as information on your AJAX request and do an action based on that name, in our case we used bordoni_query_posts.

On this AJAX request I will pass some variables to a WP_Query and return the posts as JSON so that we can use that information on the Front End. The variables I’ve decided to use for now are only a few, qty that will allow you to change how many posts you want and post_type that will allow me to query the needed type of information using WP_Query.

You should add the following PHP code to your plugin or functions.php from your theme to be able to see the JSON response on your browser console.

add_action( 'wp_ajax_bordoni_query_posts', 'bordoni_query_posts_callback' );
add_action( 'wp_ajax_nopriv_bordoni_query_posts', 'bordoni_query_posts_callback' );
function bordoni_query_posts_callback() {
	$response = [];

	// Never Use $_POST or $_GET variables without proper care Sanatization
	$query = new WP_Query( [
		'posts_per_page' => absint( $_POST['qty'] ),
		'post_type' => wp_kses( $_POST['post_type'], [] ),
	] );

	// If we don't have posts matching this query return status as false
	if ( ! $query->have_posts() ) {
		$response->status = false;

		// remember to send an information about why it failed, always.
		$response->message = esc_attr__( 'No posts were found' );
	} else {
		$response->status = true;

		// We will return the whole query to allow any customization on the front end
		$response->query = $query;

	// Never forget to exit or die on the end of a WordPress AJAX action!
	exit( json_encode( $response ) );

On our JavaScript handler we are expecting a JSON response, we will exit the action printing the $response variable encoded as JSON.

Wrapping Up

If you still have questions on how to proceed on a specific situation that I did not cover on this guide, please hit me up on the comment section below and I will be able to try to help you.

Helpful links

Similar Posts


  1. It would be great if you would include your complete code w/the wp_localize_script. I need to be able to display posts inside the function e.g. // while ( $posts->have_posts() ) { $posts->the_post(); } // etc. but I cannot figure out how to pass the information to the JS to know when there are no more posts (to hide a Load More button, for example). Any ideas?

  2. Hi, i have a problem, the functions.php is not recognizing the WP_Query, says it’s undefined, i tried to add the “wp-load.php” to the functions.php but that didn’t help, any idea? Thanks!

    1. Hi Nicolas, I just updated the code, it had a typo now it should work as expected.

      The problem was that I was using `$query = WP_Query` instead of the `$query = new WP_Query`.

      Hope this helps you! ?

    1. Hi Suprtickets,

      You don’t need a function named after the action that we referenced in the jQuery code, rather will need a connection between that action and the function.

      That is created by using the WordPress actions:

      add_action( ‘wp_ajax_bordoni_query_posts’, ‘bordoni_query_posts_callback’ );
      add_action( ‘wp_ajax_nopriv_bordoni_query_posts’, ‘bordoni_query_posts_callback’ );

      See that the `bordoni_query_posts_callback` which is the function is linked twice, one for non-logged users (`nopriv`) and one for all the logged users.

      What actually makes that connection is the filter which should be formated as `wp_ajax_{$your_action}` and `wp_ajax_nopriv_{$your_action}`.

      Was I clear on the explanation? I mean AJAX on WordPress can be a little weird at first.

    1. So normally that will be an error if you load WordPress incorrectly, or you are trying to use the method too early in the execution of the code.

      I would need more information to help you further.

  3. hi
    i use below code but doesn’t work!

    JS code:

    function (){jQuery.ajax({url:t_theme.ajax_url,type:”post”,data:{action:”comment”,post_id:t_theme.post_id};success:function(response){var rrr=jQuery.parseJSON(response); jQuery(“.commentss”).html(rrr.mycomment)


    code in `function.php`

    add_action(‘wp_ajax_comment’, ‘comment’);
    add_action(‘wp_ajax_nopriv_comment’, ‘comment’);
    function comment()
    $idpage = (int)$_POST[‘post_id’];
    $pagination = paginate_comments_links();
    $response[‘mycomment’] = ”.$pagination.”;
    echo json_encode($response,true);

    the paginate_comments_links() docent work in function.php why?!

    1. Hi Edia, thanks for the slowest response ever.

      If I can get what is the Console error that you are getting when trying to use the code above, I can help you get it working.

      Try using `$.post()` method as I displayed in the Code on the article above, it might be easier to debug it further.

      My Best regards,

Leave a Reply

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