That is actually the expected output of next_posts_link(), i.e. it always uses the current page URL. And the same also applies to previous_posts_link().
So if you\'re on the homepage (localhost/), then the URL of page 2 would be localhost/page/2, and if you\'re on (your custom post type archive page at) localhost/todo, then the URL of page 2 would be localhost/todo/page/2.
And if you want to alter the main WordPress query on the homepage, then you should use the pre_get_posts hook instead of making a secondary/custom WP_Query call (new WP_Query()) in your index.php template.
So for example, to display 3 todo posts on the homepage,
Add this to your theme\'s functions.php file:
add_action( \'pre_get_posts\', \'my_pre_get_posts\' );
function my_pre_get_posts( $query ) {
// If we\'re on the homepage, query 3 "todo" posts instead of the default ones.
if ( is_home() ) {
$query->set( \'post_type\', \'todo\' ); // query posts of the "todo" type only
$query->set( \'posts_per_page\', 3 ); // and display three posts per page
}
}
Then in your index.php template, just remove those $todos and $args, and use the default loop to display the posts returned via the main query:
<?php
// No need for the $todos and $args.
?>
<main id="primary" class="site-main">
<section class="glass">
<?php if ( have_posts() ) : ?>
<div class="todolist">
<?php while ( have_posts() ) : the_post(); ?>
<div class="todo">
... your code.
</div>
<?php endwhile; ?>
</div>
... your pagination here.
<?php endif; // end have_posts() ?>
</section>
That way, even if next_posts_link() and previous_posts_link() do not add the todo/ to the pagination links, you wouldn\'t get the error 404 when going to localhost/page/2 unless of course if there\'s no page 2 for the main query.
And if you wonder what that "main" (WordPress) query is, then check the Codex, specifically the part which says, "Save the posts in the $wp_query object to be used in the WordPress Loop.".
Also, your pagination code will show an empty bullet when there\'s no next/previous posts link, so to fix that, you\'d want to use get_previous_posts_link() instead of previous_posts_link() and get_next_posts_link() instead of next_posts_link(). Example:
<?php // this would replace the "... your pagination here." part above.
$links = \'\';
if ( $link = get_previous_posts_link( \'Previous Posts\' ) ) {
$links .= "<li>$link</li>";
}
if ( $link = get_next_posts_link( \'Next Posts\' ) ) {
$links .= "<li>$link</li>";
}
if ( $links ) {
echo "<ul>$links</ul>";
}
?>
Additionally, in your $args array, you should\'ve used paged (note the "d") and not page, i.e. \'paged\' => $paged. But I\'m just saying that so you know the correct arg is paged. :)