How to Load More Posts with AJAX Load More in WordPress

How to Load More Posts with AJAX Load More in WordPress

If you are running a WordPress blog or magazine-style website, improving user experience should always be a priority. Modern websites focus heavily on smooth interactions, fast loading times, and clean browsing experiences. This is where a Load More button powered by AJAX becomes incredibly useful. Instead of forcing users to reload an entire page or move to page 2, page 3, and so on, AJAX allows you to load new blog posts instantly without refreshing the page.

In this comprehensive guide, you’ll learn exactly how to Load More Posts with AJAX load more in WordPress, using a clean, reliable, and scalable approach. We will use a child theme, because editing core theme files directly is never recommended. This tutorial follows WordPress best practices, modern coding techniques, and SEO-friendly structure, making it helpful for both beginners and intermediate developers.

Introduction

Websites today must be interactive, fast, and user-focused. If your website displays many blog posts, loading everything at once can make the page heavy and negatively affect page speed. On the other hand, traditional pagination increases clicks and breaks the natural reading flow.

That’s why the Load More Posts with AJAX Load More in WordPress technique is becoming increasingly popular. It keeps visitors engaged, helps reduce bounce rate, and improves Core Web Vitals by loading content only when needed.

This step-by-step tutorial explains how to add Load More Posts with AJAX Load More in WordPress feature to your theme using clean code, a child theme structure, and WordPress’s built-in AJAX system.

Step 1 – Create and Set Up a Child Theme

A child theme allows you to modify your site without touching the original theme. This protects your changes from being overwritten during updates.

Inside wp-content/themes/, create a folder:

twentytwentyone-child
Plaintext

Create a style.css file:

/*
Theme Name: Twenty Twenty-One Child
Template: twentytwentyone
Text Domain: twentytwentyone
*/
CSS

This file makes WordPress recognize the child theme.

Activate your child theme

Go to Appearance > Themes and activate your new child theme.

This ensures your AJAX customization remains safe even after theme updates.

Step 2 – Enqueue CSS & JavaScript Correctly

Next, create a functions.php file inside your child theme and add the following:

<?php

function enqueue_script_style()
{
    wp_enqueue_style('leaning-style', get_stylesheet_uri());
    wp_enqueue_style('learning-bootstrap-css', get_stylesheet_directory_uri() . '/assets/css/bootstrap.min.css', array(), '1.0.0', 'all');
    wp_enqueue_script('jquery');
    wp_enqueue_script('learning-bundle-script', get_stylesheet_directory_uri() . '/assets/js/bootstrap.bundle.min.js', array(), '1.0.0', true);
    wp_enqueue_script('learning-custom-script', get_stylesheet_directory_uri() . '/assets/js/custom.js', array(), '1.0.0', true);
    wp_localize_script('learning-custom-script', 'learning_custom_script_object', array(
        'ajaxurl' => admin_url('admin-ajax.php'),

    ));
}
add_action('wp_enqueue_scripts', 'enqueue_Script_Style');
PHP

What this does:

  • Loads your stylesheet
  • Loads your custom JS file
  • Makes admin-ajax.php accessible inside JS
  • Ensures AJAX requests work for both logged-in and logged-out users

Step 3 – Display Initial Blog Posts in home.php

Create home.php inside your child theme to display the first set of posts.

<?php
get_header();

$posts_per_page = get_option('posts_per_page');
$query = new WP_Query(array(
    'post_type' => 'post',
    'posts_per_page' => $posts_per_page
));
$count = wp_count_posts();
$total_posts = $count->publish;
$category_list = get_terms(array(
    'taxonomy' => 'category',
    'hide_empty' => false,
));
?>
<div class="blog-post-wrapper">
    <div class="container">
        <div class="blog-grid">
            <?php if ($query->have_posts()) :
                while ($query->have_posts()) : $query->the_post(); ?>
                    <div class="blog-item">
                        <?php echo get_the_post_thumbnail(get_the_ID(), 'full'); ?>
                        <h3 class="blog-title"><?php the_title(); ?></h3>
                        <p class="blog-excerpt"><?php echo wp_trim_words(get_the_excerpt(), 20); ?></p>
                        <a href="<?php the_permalink(); ?>" class="blog-readmore">Read More</a>
                    </div>
            <?php endwhile;
            endif; ?>
        </div>
        <?php if ($total_posts > $posts_per_page): ?>
            <div class="load-more-btn">
                <button type="button" data-page=1>Load More</button>
            </div>
        <?php endif; ?>
    </div>
</div>
<?php get_footer(); ?>
PHP

Explanation:

  • Loads the first 5 posts
  • Wraps posts inside #post-wrapper
  • Adds a button that will load more posts when clicked

Step 4 – Write JavaScript to Trigger AJAX Request

Create a custom.js file.

Do you know how to use Ajax in WordPress? Click to Learn about it.

 jQuery(document).ready(function ($) {
 jQuery(".load-more-btn button").on("click", function () {
    var page = parseInt($(this).attr("data-page"));
    $.ajax({
      url: learning_custom_script_object.ajaxurl,
      type: "POST",
      data: {
        action: "load_more_posts",
        page: page,
      },
      success: function (response) {
        if (response.data.no_more_posts !== "") {
          $(".blog-grid").append(response.data.html);
          $(".load-more-btn button").attr("data-page", page + 1);
        }
        if (response.data.no_more_posts === true) {
          $(".load-more-btn button").hide();
        }
      },
    });
  });
  });
JavaScript

What this does:

  • Detects a click on the Load More button
  • Sends page number to PHP
  • Receives HTML and appends it to the existing post list
  • Hides the button when no more posts exist

Now add this inside your functions.php:

function load_more_posts()
{
    $page = isset($_POST['page']) ? intval($_POST['page']) : 1;
    $posts_per_page = get_option('posts_per_page');
    $count = wp_count_posts();
    $total_posts = $count->publish;
    $query = new WP_Query(array(
        'post_type' => 'post',
        'posts_per_page' => -1

    ));
    $all_posts = $query->posts;
    $start = $page * $posts_per_page;
    $length = $posts_per_page;

    $slice = array_slice($all_posts, $start, $length);
    $no_more_posts = false;
    if ($start + $length >= $total_posts) {
        $no_more_posts = true;
    }

    ob_start();
    foreach ($slice as $post) { ?>
        <div class="blog-item">
            <?php echo get_the_post_thumbnail($post->ID, 'full'); ?>
            <h3 class="blog-title"><?php echo get_the_title($post); ?></h3>
            <p class="blog-excerpt"><?php echo wp_trim_words(get_the_excerpt($post), 20); ?></p>
            <a href="<?php echo get_permalink($post); ?>" class="blog-readmore">Read More</a>
        </div>

        <?php }
    $html = ob_get_clean();

    wp_send_json_success(['html' => $html, 'no_more_posts' => $no_more_posts]);
}
add_action('wp_ajax_load_more_posts', 'load_more_posts');
add_action('wp_ajax_nopriv_load_more_posts', 'load_more_posts');
PHP

Why this works:

  • WordPress receives the AJAX call
  • It fetches the next page of posts
  • Loops through them and builds HTML
  • Sends the HTML back to JavaScript

Step 6 – Test the Load More Button

After completing the steps:

  • Visit your homepage
  • Scroll to the bottom
  • Click the Load More button

You should now see additional blog posts load instantly without refreshing the page.

Want to try it on the Image? Read: How to Load More Images on Scroll Using AJAX in WordPress

Best Practices & Common Mistakes to Avoid

  • Do NOT modify parent themes: Always use a child theme for customizations. Updating a parent theme will remove your changes.
  • Avoid loading too many posts at once: This can slow down the page.
  • Use caching wisely: AJAX calls bypass caching—consider using object caching.
  • Validate page numbers: Always sanitize AJAX input.
  • Add CSS transitions: Small animations improve UX.
  • Use placeholders: Skeleton loaders improve perceived performance.

Final Thoughts

Adding the ability to Load More Posts with AJAX Load More in WordPress is one of the simplest yet most powerful UX improvements you can make. Not only does it speed up the website, but it also improves engagement and reduces unnecessary page reloads.

By following this step-by-step tutorial, you now understand:

  • How to create a child theme
  • How to enqueue CSS/JS correctly
  • How to write AJAX-powered JavaScript
  • How to create a PHP AJAX handler
  • How to dynamically load posts without refreshing the page

Whether you run a blog, magazine, news portal, or tutorial website, this feature boosts both usability and performance.

Leave a Comment

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

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