Question: Why does WP pagination break when used on the homepage?

If you take the code below and use it in a page template it works perfectly (make sure you have 3 or more posts). However, as soon as you use the same code on home.php, front-page.php, index.php or even as a page template but set as a static homepage, it breaks.

The URL shows `/page/2/` but you get a 404 page. If you change the URL to `/?page=2` it works.

I have seen so many questions related to this all over the place, yet none have a solution that works.

For the sake of simplicity I have simplified the loop below and I'm using the default WP next and previous posts links. I don't wish to use a plugin such as WP-PageNavi or similar.

```
<?php get_header(); ?>

    <?php

        // taken from https://codex.wordpress.org/Pagination
        if ( get_query_var('paged') ) { 
            $paged = get_query_var('paged'); 
        } 
        else if ( get_query_var('page') ) {
            $paged = get_query_var('page'); 
        } 
        else {
            $paged = 1;
        }

        $wp_query = new WP_Query( array( 
            'posts_per_page' => 2,
            'paged' => $paged
        ));

    ?>

    <?php if ( $wp_query->have_posts() ) : while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>

         <?php the_title(); ?>

    <?php endwhile; endif; ?>

    <?php previous_posts_link(); ?>
    <?php next_posts_link(); ?>

    <?php wp_reset_query(); ?>

<?php get_footer(); ?>

```

Answer: 
The solution is to not alter the main query in the template. The default query happens before the template is loaded, so querying in the template overwrites that original query, which is a waste of resources. See the example in codex under [`pre_get_posts`](http://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts) for the correct way to alter the default query without pagination issues.
Also from [codex.wordpress.com/Pagination](http://codex.wordpress.org/Pagination#Advanced_Troubleshooting_Steps) (Under "**Advanced Troubleshooting Steps**" > "**Removing query\_posts from the main loop**") regarding modifying the main query via the `pre_get_posts` action mentioned by Milo:

> 
> [...] *add the query for your home and category pages back in your theme's functions.php file:*
> 
> 
> 
> ```
> function my_post_queries( $query ) {
>      // do not alter the query on wp-admin pages and only alter it if it's the main query
>     if (!is_admin() && $query->is_main_query()){
>         // alter the query for the home and category pages 
> 
>         if(is_home()){
>            $query->set('posts_per_page', 3);
>         }
> 
>         if(is_category()){
>             $query->set('posts_per_page', 3);
>         }
>     }
> }
> add_action( 'pre_get_posts', 'my_post_queries' );
> 
> ```
> 
> 

So your implementation might look something along the lines of

```
function modify_query( $query ) {
    if( !$query->is_main_query() )
        return;  //Only wish to modify the main query

    //Modify the query vars for the home and front pages
    if( is_home() || is_front_page() ) {
        $paged = get_query_var('page');

        //If the 'page' query var isn't set, or didn't return an integer, default to 1
        $paged = !isset( $paged ) || !is_int( $paged ) ? $paged : 1;

        $query->set( 'paged', $paged );
        $query->set( 'posts_per_page', 2 );
    }
}
add_action( 'pre_get_posts', 'modify_query' );        

```