Canonical Links are something that comes up quite often when building Dnn modules that host content, like blogs, forums, e-commerce sites and more. As is typical of something released and easy to implement, a lot of different solutions appeared.
Quietly included in the 7.4.1 release of Dnn Platform was the ability to set the Canonical Url Link for a page by using a Page Base property, rather than by injecting your own specific link. This post will cover how to use that change to generate Canonical links in your Dnn modules.
What is a Canonical Link?
If you’re not familiar with the term, a Canonical Link is a specific piece of html included in your <head> section. This defines, for the page, what the ‘Canonical’ Url is. Canonical just means ‘definitive’, and is used by search engines so that, if they find two pages with the same content, they know which is the correct one to include in search engines.
A canonical link looks like this:
<link href=”http://example.org/a-canonical-url” rel=”canonical” />
If you search the world-wide-web, you’ll find many different ways of creating a canonical link in Dnn. Some of them may even be written by me. But this is now the Canonical blog post on this topic (see what I did there?).
PageBase.CanonicalLinkUrl
The Dnn Page Base class defines multiple properties of the page of content being created. The namespace of this class is DotNetNuke.Framework.CDefault. This class includes the Title and the Description, and now also includes a property called CanonicalLinkUrl. If a value is found in this field, then Dnn will include the value inside a Canonical Link placed inside the <head> section of the page.
Setting the Canonical Url is then just a case of setting the value of this field. If Dnn sets the value of the Canonical Url at any point during the page lifecycle, any module that sets the value will overwrite the default value. The eventual ‘winner’ depends on who sets it the last time. Unless you have multiple modules on the same page trying to set the value, it should be your module.
The page title works in the same way – it is set according to the page properties of the current page, but any module is able to override that value and have the page title change.
Code Example
I wrote a very short example module to show how this is used. This module just sets the value of the Canonical Url to the value of the current page, unless a specific querystring is found.
Here is the code:
No you can’t copy paste all of that (it’s an image), so here’s the relevant piece you want:
1) You need to define the Base Page as an accessible property:
public DotNetNuke.Framework.CDefault BasePage {
get { return (DotNetNuke.Framework.CDefault)this.Page; }
}
2) You need to then set the CanonicalLinkUrl property with your value:
//set the CanonicalLinkUrl property of the page
this.BasePage.CanonicalLinkUrl = canonicalUrl;
The rest of the code is just filling to show how it works.
Showing the Results of the Canonical Url Link Code
The code above shows four different behaviours – the first being when the page is requested as normal, with no extra parameters or querystring items.
Here I request the page with the normal URL, and we get the page Url back. Note that in the code, I am doing this by calling the Friendly Url Provider with the actual TabId for the page – I do this because I want the unadorned URL of the page – if you add a ?test=whatever to the URL it will be ignored. If we just repeat what the requested URL is back out, then we are achieving nothing in terms of eliminating duplicate content.
You can see that the Canonical Link element just emits the same Url as the page, which is what we want in this scenario.
However, in many cases you have a different Url for a specific piece of code, such as when you load up a Blog post based on a Content Id. Or we might load up a product in an e-commerce catalog. Sometimes these Urls get adorned with other pieces of querystring which we don’t want acting as duplicate content – perhaps they are coupon codes, tracking codes or just a bad link from somewhere. The solution is to identify the piece of content and set the Canonical Link that you want for the page showing that content – regardless of the exact format of the Url.
This example shows the result of sending the results as we want them. The requested Url has the querystring of ?option=2 – the code specifically states that this should be /option/2/something/else – so the Canonical Url is generated and placed into the Canonical Url link.
Wrapping Up the Canonical Url Story
This simple example shows how to use the Canonical Url page property – if you are developing Dnn modules which need to be optimized for Search Engines, you need to make the changes to take advantage of this ability to directly control the Canonical Url from within the code itself. If you need to release code that spans an install base earlier than 7.4.1, you could use some simple reflection to see if the property is available – but you’d need to cache the results so you aren’t continually running expensive reflection code.