Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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?

share|improve this question
    
What is creating the canonical URL link? Last I checked WordPress does not do that by default. –  s_ha_dum Feb 5 '13 at 22:27
2  
WordPress, as of version 3.x? In order to remove it you have to include remove_action('wp_head', 'rel_canonical') –  N2Mystic Feb 5 '13 at 22:42
    
I stand corrected. –  s_ha_dum Feb 5 '13 at 22:51
    
@N2Mystic The rel_canonical function was introduced in WordPress 2.9 –  bungeshea Feb 6 '13 at 5:32

1 Answer 1

up vote 5 down vote accepted

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="%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="%s" />', user_trailingslashit( $link . $prev ) );
        else
            printf ( "\n" . '<link rel="prev" href="%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="%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.

share|improve this answer
    
+1 Looks good. Thanks! –  N2Mystic Feb 7 '13 at 5:21
1  
@bungeshea Can you please explain more about what your script does to resolve this issue? How is this any different to the default canonical print? And it appears to have a problem, it prints \n on the page rather than making a new line. I wrote a question about this here: wordpress.stackexchange.com/questions/87514/… –  Christine Cooper Feb 19 '13 at 19:39
    
I just tested this on a fresh install of WP 3.5.1 and I cannot see what it is doing different to the default WP function that adds canonical to the header. The href link is the same on all pages which is no different to the original function. Unless of course, I am missing something here? Or maybe there is a typo in your script? –  Christine Cooper Feb 19 '13 at 19:56
1  
@bungeshea Thank you for the update, although this script remains incomplete as it is missing the link rel="next" and rel="previous". Without them, Google will index each page of the post as a separate entry. I wrote more about this in my Update 2: wordpress.stackexchange.com/questions/87514/… Is there any chance that you can kindly add this feature to your script so that we can finally have a solution to this problem? Note that there should not be a rel="prev"/"next" if there isn't a page after/before it. –  Christine Cooper Feb 21 '13 at 14:42
1  
@ChristineCooper Have a look at the updated code in my post. I've tested it thoroughly on WordPress 3.6-alpha. It will add the page number to the canonical links for posts with pagination, and prev/next links to pages before and after it (if they exist). For posts without pagination, the regular permalink will be the canonical link and no prev/next links will be added. Thanks again for pointing out the issues that I missed. Enjoy! –  bungeshea Feb 24 '13 at 4:31

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.