Canonical URLs without using a WordPress Plugin

and published
add canonicals in WordPress without plugin

Everyone that knows me will know that I hate using WordPress plugins, not that I’m a website designer that believes that every other designer and coder should write their own code, far from it. I’m a web designer that believes you should only use trusted plugins when you absolutely need to. Using a plugin that offers you 100 features when you only need one, makes no sense to me! Using such a plugin is only going to bloat your code, slow down your SQL and increase the chances of exploitable vulnerabilities.

Whenever possible you should avoid using WP plugins unless you absolutely need to, if you’re looking to use just canonical URLs then you don’t need a fancy all dancing all singing SEO plugin, you can add canonical URLS to WordPress without a plugin, in fact in this short guide I’ll provide you the code that with work with any content management system that uses PHP.

WordPress SEO Plugins

I do however recommend Yoast SEO or any other reputable SEO plugin if you want better SEO management, such as changing titles and meta descriptions but only if you need this… a 5-page business website doesn’t really require an SEO plugin because everything you can do with the plugin you can do without, of course, it might take you 20mins more! But the end results will be a site that is easier to upgrade without fear of something going wrong and a cleaner SQL database.

Universal PHP Code for Canonical URLS

Below is the code that you need to add within the head of your theme template:

<link rel="canonical" href="https://www.bybe.net<?php echo $_SERVER['REQUEST_URI'];?>">

The above code will be added to all pages, it will protect you from duplicates from www/non-www, https/http, shortlinks and query strings suffix, this is because of your www/non-www, domain and protocol are hard set, the PHP command $_SERVER[‘REQUEST_URI’] will return the relative url and suffix it to the end of your URL and therefore make a absolute URL.

It will be used on catagories, tags, author, indexes and achieves, these pages are not considered as duplicate by Google or Bing because snippets of various pages on one page is a unique combination.

The only reason I can think of when you should NOT use canonical links on those pages is when you are displaying full articles on those pages without any other articles on the same page, therefore this would be considered duplicate. I do however recommend for UX purposes (User Experience) that you do not use this format in any case.

Not Recommended Method

If for some mad reason you would prefer not to use canonical on categories, tags, author, indexes and achieves pages then you can use the code below:


<?php
    // For most people this method should be avoided... use the one above!
    if(is_singular()) {
        // Canonicals used on Posts and Pages Only!
        echo '<link rel="canonical" href="https://www.bybe.net' . $_SERVER['REQUEST_URI'] . '">';
    } else {
        // Do Nothing!
    }
?>

Adding canonical Links in WordPress

Below are a few easy steps that will have you up and running with WordPress canonical URLs in no time at all, and without a plugin.

  1. Login to WordPress
  2. Hover over Appearance
  3. Click Editor
  4. Find Theme Header (header.php)
  5. Add the Universal PHP Code for Canonical URLS found above within the HEAD section of your theme header file.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

35 Responses to “Canonical URLs without using a WordPress Plugin”

  1. Dheeraj sharma

    Nice Post Simon

    Reply
  2. This didn’t work for me

    Reply
    • Actually it does – needed the full url!! 😀

      Reply
      • Also, it now says that certain pages are blocked from being crawled – the ones that had the duplicate issues – so I guess that’s a good thing? As I don’t want them being indexed.

        Reply
        • Ah wait… they all show up with a / at the end – is there anyway to remove this /?
          As just want the page .html not .html/

          Reply
          • Sorry but its not compatible with extensions. In this day and age there is never any need to use .php, .html extensions. URLS are better short in terms of user experience and SEO.

  3. Anthony Tornambe

    Nice, It works fine.

    Reply
  4. Creativelopers

    If this is done, will it affect posts that dates as far back as 2012?

    Reply
  5. Great tutorial, I added the canonical tag and it improves my website appearance.

    Reply
  6. Sorry, I forgot to include the code tags.

    Reply
  7. Okay, apparently you can’t actually include code in the comments. TLDR; Your tag is missing a forward slash before the closing bracket.

    Reply
  8. Very cool 🙂 Damn awesome to do this without a plugin. Question though….sometimes one actually needs to fire the rel-cannon at a target rather than at itself. How do you implement that with your excellent solution?

    Reply
    • Hi Dove, the code is very simple and ideal for sites that only require internal canonical links. You could however adapt the code and have it use WordPress Conditional Tags but for a large volume of pages this would not be ideal.

      Another option would be to have a custom field but you would need to edit your LOOP to include it. If you want to keep things simple I recommend you use Yoast SEO for external URLS, this will set canonicals locally by default and should you want to use an external source then simply click advanced before you publish the page and enter the external URL.

      Picture of Yoast external canonical option:

      Yoast WordPress Canonical URLS

      Reply
  9. Does this work for sites that recently switched from http to https? I added the code but I am still getting canonical errors

    Reply
    • Yes, this works for both HTTPS and HTTP websites, see below:

      • Websites without SSL use:
        <link rel="canonical" href="http://www.example.co.uk<?php echo $_SERVER['REQUEST_URI'];?>">
      • Websites with SSL use:
        <link rel="canonical" href="https://www.example.co.uk<?php echo $_SERVER['REQUEST_URI'];?>">

      Note: replace example.co.uk with your own domain name

      Reply
  10. Great post, I have a question.

    How can I do to put the manual canonical tag in the header of a single post.

    I want to tell google that a post is the main one. MY problem is that there are two articles that are cannibalized keywords.

    Thanks

    Reply
    • Hi Eduard,

      You can do this by using is_page() and speificly adding the code required for the matching page, for example this would look something like:

      
      <?php if(is_page('1')) { // Manual Canonical ?>
          // This will be added on page ID 1 and URL indicated otherwise change the ID and URL.
          echo '<link rel="canonical" href="https://www.bybe.net/services/responsive-website-design/">';
      }
      ?>
      
      

      If you wish to use it on multiple pages then you could use something like this:

      
      <?php if(is_page('1')) {
          // This will be added on page ID 1 and URL indicated otherwise change the ID and URL.
          echo '<link rel="canonical" href="https://www.bybe.net/services/responsive-website-design/">';
      } else if (is_page('2')) { 
          // This will be added on page ID 1 and URL indicated otherwise change the ID and URL.
          echo '<link rel="canonical" href="https://www.bybe.net/services/responsive-website-design/">';
      } else {
          // This will be added on all pages apart from page IDs 1 and 2
          echo '<link rel="canonical" href="https://www.bybe.net' . $_SERVER['REQUEST_URI'] . '">';
      }
      ?>
      
      Reply
  11. Sorry to disappoint you all but this is a nonsense job, doing more harm than good for SEO. Canonical tags are for telling Google of all the URLs loaded that produce the same content which one is the official URL, but this code tells Google that any URL you load is the official one. Total nonsense. More harm than doing nothing at all, every time, without exception! For someone who says that avoid unnecessary plugins you really ought to either take this post down or better yet change to code to output the genuine canonical URL rather than saying that every URL if you don’t mind the extra researh! Think how many sites you’re trashing with this nonsense post!

    Reply
    • Hi Dan, I’m not disappointed and but do believe your comment could have been more polite and contained constructive feedback. You do however raise a good point that I would like to address.

      It is a massive misconception by most web designers, webmasters and even a lot of SEO’ers that canonicals should be reserved purely for ‘singular pages’ and not on pages such as tags, categories, author and so on, this is completely untrue and canonicals are perfect for those type of pages.

      Tag, Catagories, Author Pages and even Archive pages often contain snippets of text, while these content snippets are duplicate, the combination of the content present on the page is unique, think about it for a moment, does my Web Design Catagory look like any of the articles or other categories? no, therefore the content is not duplicate.

      Yoast SEO which has over 95 million downloads and is the most SEO used plugin for WordPress, this plugin uses canonical on all those type of pages by default, also most of the top websites in teh world use canonicals in this manner, take Amazon as a prime example, no pun intended.

      Therefore the code on this page is perfectly acceptable and your comment is unfounded to say the least, the code on this page protects websites against:

      WWW / NON-WWW Duplicates
      HTTPS / HTTP Duplicates
      Shortlink Duplicates
      Query Strings Suffix Duplicates

      PS. I have added a solution for users not wanting to add canonical links to those type of pages, whatever the reason.

      Reply
    • Sorry Simon, Dan is right, it does NOT make any sense to always set the canonical to the $_SERVER[‘REQUEST_URI’]. This is SEO-harmful code and I´d advice everybody to NOT use this.

      Reply
      • Sorry, but your comment just as unfounded as the last. If you have evidence to support otherwise then by all means let us all know.

        Reply
  12. Thanks Simon.

    I had the following added to my header.php:

    I then started to use Yoast SEO and they are also adding a second, identical canonical link into the header, leaving me with two of them. This seems to be bad practice though, so now my question: Can i just remove the hardcoded one leave the Yoast in there or is there anything Im missing?

    Thanks 🙂
    Chris

    Reply
    • Yep, using the code provided on this page with Yoast SEO is pointless. Personally, I use Yoast SEO myself but on sites that want a low plugin footprint then this code rocks.

      Reply
  13. Amit Ombale

    Thanks a lot Simon… Its working for me very cool… it showed me the result immediately.

    Reply
  14. Hi Simon, thanks for the fantastic article! Quick question…

    I’ve just started using SEMrush with my website and one of my errors is duplicate meta descriptions between https://letsprint3d.net and https://letsprint3d.net/ which is something I would like to fix. I looked at the source of my homepage and it does have a canonical tag set in the header, I believe this is being generated by the Yoast SEO plugin..

    Do you have any idea what would be causing this issue, where the two different versions are being detected as duplicate meta descriptions?

    Reply
    • Hi Brett,

      Canonical links will prevent Google or Bing indexing pages such as those that appear to duplicate with a trail ending slash, it sounds to me that SEMRush is giving a false positive. Personally, I wouldn’t use SEMRush to find duplicate pages, meta descriptions or page titles, why? because Google Search Console and Bing Webmaster tools report these kinds of things and well, I’m more inclined to trust them over a 3rd party. Furthermore, if you are using Yoast SEO you do not need this code on this page. Lastly to prevent duplicate descriptions and page titles occurring on pagination type pages then you can use Yoast SEO variables, for example: title: Blog articles of bits and bobs page %%pagenumber%% of %%pagetotal%% would return Blog articles of bits and bobs page 1 of 10 meaning that every page would have a unique number thanks to the page number.

      Reply
  15. Hi there,

    Do we have to change the website name <link rel="canonical" href="https://www.bybe.net"> in the code to our own website?

    Reply
  16. Yevhenii Matviichuk

    Thanks a lot! It worked for me. Just put the code (with changing bybe.net URL to your website`s URL) into header.php file in your theme in part…

    Reply
  17. How about if you want to add the canonical url for custom taxonomies? What is the code for that?

    For some reasons I don’t know, yoast is not adding canonical url for custom taxonomies.

    Reply
  18. Hi Simon, nice article, I have one question, my website is on asp.net, I want to add canonical tag on every page of website, will this code work

    <link rel="canonical" href="http://www.example.com>

    . or do I need to edit the code, can you help in this, thanks.

    Reply
  19. Great job thank you

    Reply
  20. Hello, its the best solution I got from your explanation above. Very much intuitive and helpful. Keep on

    Reply