I want to create an AJAX numeric pagination. And found code in a website. And it works perfectly at first click event, but on the second click it doesn't. If I click in pagination page 4, it works perfectly (And doesn't load page, because of ajax)


but after the first click, if i click on the 5th page link over the pagination, the whole page loads (not as expected in ajax) will go to a blank page and url is:


php code for TwentyFifteen Child theme's function.php

if ( !function_exists( 'custom_style_script_enqueue' ) ) :

    function custom_style_script_enqueue() {
        global $wp_query;

        wp_enqueue_style( 'custom-stylesheet', get_theme_file_uri( 'css/custom-style.css' ), array( '' ), filemtime( get_theme_file_path( 'css/custom-style.css' ) ), 'all' );
        if ( ! wp_script_is( 'jquery', 'enqueued' ) ) {
            wp_enqueue_script( 'jquery' );
        wp_register_script( 'custom-ajax-jscript', get_theme_file_uri( 'js/custom-ajax-jscript.js' ), array( 'jquery' ), filemtime( get_theme_file_path( 'js/custom-ajax-jscript.js' ) ), false );
        wp_localize_script( 'custom-ajax-jscript', 'ajaxpaginationobject', array(
            'ajax_url' => admin_url( 'admin-ajax.php' ),
            'query_vars' => json_encode( $wp_query->query )
        ) );
        wp_enqueue_script( 'custom-ajax-jscript' );
    add_action( 'wp_enqueue_scripts', 'custom_style_script_enqueue' );


if ( !function_exists( 'my_ajax_custom_pagination' ) ) :

    function my_ajax_custom_pagination() {
        $query_vars = json_decode( stripslashes( $_POST['query_vars'] ), true );
        $query_vars['post_type'] = 'post';
        $query_vars['paged'] = $_POST['page'];
        $query_vars['post_status'] = 'publish';
        $query_vars['posts_per_page'] = 3;

        $posts = new WP_Query( $query_vars );
        $GLOBALS['wp_query'] = $posts;

        add_filter( 'editor_max_image_size', 'my_image_size_override' );

        if ( ! $posts->have_posts() ) {
            get_template_part( 'content', 'none' );
        } else {
            while( $posts->have_posts() ) {
                get_template_part( 'content', get_post_format() );
        remove_filter( 'editor_max_image_size', 'my_image_size_override' );

        the_posts_pagination( array(
            'prev_text' => __( 'Previous page', 'twentyfifteen' ),
            'next_text' => __( 'Next page', 'twentyfifteen' ),
            'before_page_number' => '<span class="meta-nav screen-reader-text">' . __( 'Page', 'twentyfifteen' ) . '</span>',
        ) );


        function my_image_size_override() {
            return array( 825, 510 );

    add_action( 'wp_ajax_ajax_paginaton', 'my_ajax_custom_pagination' );
    add_action( 'wp_ajax_nopriv_ajax_paginaton', 'my_ajax_custom_pagination' );


And JS file custom-ajax-jscript.js

    function find_page_number( element ) {
        return parseInt( element.html() );

    // $( ".nav-links a" ).click( function(e) {
    // $(document).on( 'click', '.nav-links a', function(e) {
    $( "nav.navigation" ).on( "click", ".nav-links a", function(e) {

        page = find_page_number( $(this).clone() );

            url: ajaxpaginationobject.ajax_url,
            // type: 'POST', // I'll use 'method' instead of 'type' because my jquery version is NOT PRIOR then 1.9.0
            method: 'POST',
            data: {
                action: 'ajax_paginaton',
                query_vars: ajaxpaginationobject.query_vars,
                page: page
            beforeSend: function() {
                $('#main').find( 'article' ).remove();
                $('#main nav').remove();
                $('#main').append( '<div class="page-content" id="loader">Loading New Posts...</div>' );
            success: function( html ) {
                $('#main #loader').remove();
                $('#main').append( html );

Why second click does't work and include some extra part (/wp-admin/admin-ajax.php/) in middle of page link?

Please help me to solve this problem.

1 Answer 1


Have you checked with js Console that the ajax returned the expected data['html']?

The url you show after the second page click attempt has /admin-ajax.php/ inside it. That shouldn't happen. It's a good indicator that the ajax transfer or the returned output/query is at some point broken.

Would have been useful, if you also show the relevant html parts. Without it we can't check whether the page = find_page_number( $(this).clone() ); is a proper and best-practice function.

To me it seems the $GLOBALS['wp_query'] = $posts; can be also problematic part. Why do you need to modify globals directly? It's not the common/best practice as i know.

I recommend this well detailed explanation on WP Query types and their proper usage for everyone, who feels not 110% familiar with the WP query-system.

(p.s.: have you managed to solve this problem several months back then? Maybe to answer on your own question or make an Update would be useful for others, in case you solved this issue. Cheers)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.