5

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?

4
  • What is creating the canonical URL link? Last I checked WordPress does not do that by default.
    – s_ha_dum
    Commented Feb 5, 2013 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
    Commented Feb 5, 2013 at 22:42
  • I stand corrected.
    – s_ha_dum
    Commented Feb 5, 2013 at 22:51
  • @N2Mystic The rel_canonical function was introduced in WordPress 2.9
    – shea
    Commented Feb 6, 2013 at 5:32

1 Answer 1

5

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.

17
  • 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
    Commented Feb 19, 2013 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
    Commented Feb 19, 2013 at 19:56
  • @bungeshea Does this only take affect on Pages? If so, can you please demonstrate how to use it for Posts? I ran another test with your code and I can confirm that on Posts, the href link stays the same on every page (meaning that it does not function correctly).
    – Christine Cooper
    Commented Feb 19, 2013 at 20:25
  • 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
    Commented Feb 21, 2013 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!
    – shea
    Commented Feb 24, 2013 at 4:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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