Pagination 404s on custom query

There are a couple of things I don’t understand here, but I’ll try answering them as I go along.

You have a home.php, which I assume is your default homepage. You have one line of code in there, and that is to call a another page template. Here is you code

  <?php require dirname( __FILE__ ) . '/blog-page.php'; 

In blog-page.php you have the complete page template. My question is, why are you doing this. Why not just add the content of blog-page.php into home.php? Would make more sense.

You are not using the main query to run your loop, but a custom one, which I also don’t understand, as your custom query does exactly the same as the main query, except for posts per page. This whole custom query can be avoided by just using pre_get_posts to set a custom number of posts on your homepage.

function posts_on_homepage( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'posts_per_page', '5' );
    }
}
add_action( 'pre_get_posts', 'posts_on_homepage' );

You can just add this into functions.php which will set your amount of posts on your homepage to 5, and then you can replace the custom query with a normal loop.

One thing to keep in mind here, whenever you run a custom query, pagination will fail as stated in the comments.

You will need to have a look at WP_Qeury‘s pagination parameters.

paged (int) – number of page. Show the posts that would normally show up just on page X when using the “Older Entries” link.

page (int) – number of page for a static front page. Show the posts that would normally show up just on page X of a Static Front Page.

So your query should look like this for normal pages

$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$query = new WP_Query( array( 'paged' => $paged ) );

And like this for static pages

$paged = ( get_query_var('page') ) ? get_query_var('page') : 1;
$query = new WP_Query( array( 'paged' => $paged ) );

You are also resetting your postdata twice. You should only do that once. BTW wp_reset_query(); is wrong, it is only used for query_posts that should not be used. You should be using wp_reset_postdata();

Lastly, when using a custom query, you have to specify the maximum namber of pages for next_posts_link by using the $max_pages parameter, otherwise it will fail.

 next_posts_link( 'Older Entries', $the_query->max_num_pages );

Here is an example of a proper working custom query as from the codex

<?php
// set the "paged" parameter (use 'page' if the query is on a static front page)
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;

// the query
$the_query = new WP_Query( 'cat=1&paged=' . $paged ); 
?>

<?php if ( $the_query->have_posts() ) : ?>

<?php
// the loop
while ( $the_query->have_posts() ) : $the_query->the_post(); 
?>
   <?php the_title(); ?>
<?php endwhile; ?>

<?php

// next_posts_link() usage with max_num_pages
next_posts_link( 'Older Entries', $the_query->max_num_pages );
previous_posts_link( 'Newer Entries' );
?>

<?php 
// clean up after our query
wp_reset_postdata(); 
?>

<?php else:  ?>
   <p><?php _e( 'Sorry, no posts matched your criteria.' ); ?></p>
<?php endif; ?>

I hope this will shed some light on your problem