This took some time to figure out because my custom post type query was interfering with the global query object. This is a little hack that I found on stack exchange that helped me solve the issue.
$paged = ( get_query_var( 'page' ) ) ? get_query_var( 'page' ) : 1; $args = array( 'post_type' => array( 'custom-post-type-1', 'custom-post-type-2' ), 'posts_per_page' => '3', 'nopaging' => false, 'paged' => $paged, ); $query = new WP_Query( $args ); global $wp_query; // Put default query object in a temp variable $tmp_query = $wp_query; // Now wipe it out completely $wp_query = null; // Re-populate the global with our custom query $wp_query = $query; ?> <div id="posts"> <?php if ( $query->have_posts() ) : while ( $query->have_posts() ) : $query->the_post(); ?> <div class="post <?= get_the_category()[0]->slug; ?>"> <h4><a href="#" target="_blank"><?php the_title(); ?></a></h4> <div class="content"> <?php the_content(); ?> </div> </div> <?php endwhile; endif; ?> </div> <?php echo '<div class="pagination">'; previous_posts_link( '« Newer posts' ); next_posts_link( 'Older posts »', $query->max_num_pages ); echo '</div>'; // reset post data wp_reset_postdata(); // Restore original query object $wp_query = null; $wp_query = $tmp_query;