Multi-page posts do not get indexed by Google due to canonical URLs

I’ve just noticed that on my paginated posts, only the main page gets indexed in Google. The paginated posts “post-title/2” and “post-title/3” for example, do not get indexed.

On closer inspection, it appears that WordPress creates the same canonical URL for all pages in a paginated sequence. So, the canonical for page 2 is the same for page 1, etc. So when google crawls page 2+, the canonical directs them back to the first page.

Any clues how to go about resolving this to get a more intelligent canonical url on paginated posts and pages?

1
1

You will need to replace the default rel_canonical function to do this:

function wpse_84647_rel_canonical() {

    /* Only affect singular posts. Exit early if Yoast SEO is doing this for us */
    if ( ! is_singular() || class_exists( 'WPSEO_Frontend' ) )
        return;

    /* Get the post permalink */
    $post = get_queried_object();
    $link = trailingslashit( get_permalink( $post->ID ) );

    /* Get the number of pages the post is split into */
    $numpages = substr_count( $post->post_content, '<!--nextpage-->' ) + 1;

    /* Get the current pagination page number */
    $page = ( get_query_var( 'page' ) ? get_query_var( 'page' ) : 1 );

    /* Add the page number if the post is paginated */
    if ( $numpages && $page > 1 )
        $canonical = user_trailingslashit( $link . $page );
    else
        $canonical = get_permalink( $post->ID );

    /* Output the canonical link */
    printf ( "\n" . '<link rel="canonical" href="https://wordpress.stackexchange.com/questions/84647/%s" />', $canonical );

    /* Add the adjacent rel links */
    if ( $page > 1 ) {
        remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 );
        /* Link to the previous adjacent post */
        $prev = $page - 1;
        if ( $prev > 1 )
            printf ( "\n" . '<link rel="prev" href="https://wordpress.stackexchange.com/questions/84647/%s" />', user_trailingslashit( $link . $prev ) );
        else
            printf ( "\n" . '<link rel="prev" href="https://wordpress.stackexchange.com/questions/84647/%s" />', get_permalink( $post->ID ) );
    }
    if ( $page < $numpages ) {
        remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 );
        /* Link to the next adjacent post */
        $next = $page + 1;
        printf ( "\n" . '<link rel="next" href="https://wordpress.stackexchange.com/questions/84647/%s" />', user_trailingslashit( $link . $next ) );
    }
    print "\n";
}

remove_action( 'wp_head', 'rel_canonical' );
add_action( 'wp_head', 'wpse_84647_rel_canonical', 9 );

This new function adds gets the paginated page from the URL and adds it to the canonical link. It will also add next and previous links to the adjacent pages so Google knows

Also, if you use Yoast’s WordPress SEO plugin you will not need this snippet, as the plugin handles canonical links for you.

Leave a Comment