First archive page with a few posts

This is my archive template — page-archive.php, which I am using as
a template to display all my posts/recipes

So if you’re using a Page (post of the page type) with a custom/specific Page Template, then you should create a secondary query and loop for retrieving and displaying your recipes/posts.

But even with a default archive template such as the archive.php file, you should not use query_posts() in the template!

And here’s why: (bold and italic formatting was added by me)

This function will completely override the main query and isn’t
intended for use by plugins or themes
. Its overly-simplistic
approach to modifying the main query can be problematic and should be
avoided wherever possible. In most cases, there are better, more
performant options
for modifying the main query such as via the
‘pre_get_posts’
action within
WP_Query.

It should be noted that using this to replace the main query on a page
can increase page loading times, in worst case scenarios more than
doubling the amount of work needed or more. While easy to use, the
function is also prone to confusion and problems later on. See the
note further below on caveats for details.

— See https://developer.wordpress.org/reference/functions/query_posts/ for the caveats mentioned above and other details.

And here’s how can you convert your query_posts() code to using a secondary query/WP_Query and loop instead:

  1. Replace the <?php query_posts('post_type=post&post_status=publish&posts_per_page=24&paged='. get_query_var('paged')); ?> with this:

    <?php
    // you could also do $query = new WP_Query( 'your args here' ), but I thought
    // using array is better or more readable :)
    $query = new WP_Query( array(
        'post_type'      => 'post',
        'post_status'    => 'publish',
        'posts_per_page' => 24,
        'paged'          => get_query_var( 'paged' ),
    ) );
    ?>
    
  2. Replace the have_posts() with $query->have_posts(), and the the_post() with $query->the_post(). I.e. Use the $query variable created above.

  3. And finally, replace the wp_reset_query() with wp_reset_postdata().

Now, as for displaying only a few posts on the first page, i.e. different than your posts_per_page value..

The proper solution would be to use an offset, like so:

  1. Replace the snippet in step 1 above with this, or use this instead of that snippet:

    <?php
    // Define the number of posts per page.
    $per_page  = 12; // for the 1st page
    $per_page2 = 24; // for page 2, 3, etc.
    
    // Get the current page number.
    $paged     = max( 1, get_query_var( 'paged' ) );
    // This is used as the posts_per_page value.
    $per_page3 = ( $paged > 1 ) ? $per_page2 : $per_page;
    
    // Calculate the offset.
    $offset = ( $paged - 1 ) * $per_page2;
    $diff   = $per_page2 - $per_page;
    $minus  = ( $paged > 1 ) ? $diff : 0;
    
    $query = new WP_Query( array(
        'post_type'      => 'post',
        'post_status'    => 'publish',
        'posts_per_page' => $per_page3,
        'offset'         => $offset - $minus,
    ) );
    
    // Recalculate the total number of pages.
    $query->max_num_pages = ceil(
        ( $query->found_posts + $diff ) /
        max( $per_page, $per_page2 )
    );
    ?>
    
  2. Replace the <?php numeric_posts_nav(); ?> with <?php numeric_posts_nav( $query ); ?>.

  3. Edit your pagination function — replace this part (which is lines 775 – 787 here):

    function numeric_posts_nav() {
    
        if( is_singular() )
            return;
    
        global $wp_query;
    
        /** Stop execution if there's only 1 page */
        if( $wp_query->max_num_pages <= 1 )
            return;
    
        $paged = get_query_var( 'paged' ) ? absint( get_query_var( 'paged' ) ) : 1;
        $max   = intval( $wp_query->max_num_pages );
    

    with this:

    function numeric_posts_nav( WP_Query $query = null ) {
    
        global $wp_query;
    
        if ( ! $query ) {
            $query =& $wp_query;
        }
    
        if( $query->is_singular() || $query->max_num_pages <= 1 ) {
            return;
        }
    
        $paged = get_query_var( 'paged' ) ? absint( get_query_var( 'paged' ) ) : 1;
        $max   = intval( $query->max_num_pages );
    

That’s all and now check if it works for you! 🙂