Learn More





DNN Community Blog

The Community Blog is a personal opinion of community members and by no means the official standpoint of DNN Corp or DNN Platform. This is a place to express personal thoughts about DNNPlatform, the community and its ecosystem. Do you have useful information that you would like to share with the DNN Community in a featured article or blog? If so, please contact .

The use of the Community Blog is covered by our Community Blog Guidelines - please read before commenting or posting.

Create a Canonical Url Link in Dnn by using the CanonicalLinkUrl property

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=”” 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?).



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:

Set Canonical Link Url for Dnn Module

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.


Willem Bonekamp
Great you can use this in your custom module but can you enable this for the pages in DNN as well.

I like to generate this code for each page and have in the head code of each page:

Is this core functionality of is there a module available for this?
Willem Bonekamp Monday, March 14, 2016 7:02 AM (link)
Bruce Chapman
@Willem if you use the Canonical mode for the site alias then it will show the canonical link in each page. However this is always just the URL of the page reflected back - in general it's when you implement third party modules that you tend to get duplicate URLs.
Bruce Chapman Friday, March 18, 2016 3:05 AM (link)

Comment Form

Only registered users may post comments.


2sic Daniel Mettler (124)
Aderson Oliveira (15)
Alec Whittington (11)
Alex Shirley (10)
Andrew Nurse (30)
Anthony Glenwright (5)
Antonio Chagoury (28)
Ash Prasad (21)
Ben Schmidt (1)
Benjamin Hermann (25)
Benoit Sarton (9)
Beth Firebaugh (12)
Bill Walker (36)
Bob Kruger (5)
Brian Dukes (2)
Brice Snow (1)
Bruce Chapman (20)
Bryan Andrews (1)
cathal connolly (55)
Charles Nurse (163)
Chris Hammond (203)
Chris Paterra (55)
Clinton Patterson (28)
Cuong Dang (21)
Daniel Bartholomew (2)
Dave Buckner (2)
David Poindexter (3)
David Rodriguez (2)
Doug Howell (11)
Erik van Ballegoij (30)
Ernst Peter Tamminga (74)
Geoff Barlow (6)
Gifford Watkins (3)
Gilles Le Pigocher (3)
Ian Robinson (7)
Israel Martinez (17)
Jan Blomquist (2)
Jan Jonas (3)
Jaspreet Bhatia (1)
Jenni Merrifield (6)
Joe Brinkman (268)
John Mitchell (1)
Jon Henning (14)
Jonathan Sheely (4)
Jordan Coopersmith (1)
Joseph Craig (2)
Kan Ma (1)
Keivan Beigi (3)
Ken Grierson (10)
Kevin Schreiner (6)
Leigh Pointer (31)
Lorraine Young (60)
Malik Khan (1)
Matthias Schlomann (15)
Mauricio Márquez (5)
Michael Doxsey (7)
Michael Tobisch (3)
Michael Washington (202)
Mike Horton (19)
Mitchel Sellers (28)
Nathan Rover (3)
Navin V Nagiah (14)
Néstor Sánchez (31)
Nik Kalyani (14)
Peter Donker (52)
Philip Beadle (135)
Philipp Becker (4)
Richard Dumas (22)
Robert J Collins (5)
Roger Selwyn (8)
Ruben Lopez (1)
Ryan Martinez (1)
Salar Golestanian (4)
Sanjay Mehrotra (9)
Scott McCulloch (1)
Scott S (11)
Scott Wilkinson (3)
Scott Willhite (97)
Sebastian Leupold (80)
Shaun Walker (237)
Shawn Mehaffie (17)
Stefan Cullmann (12)
Stefan Kamphuis (12)
Steve Fabian (31)
Timo Breumelhof (24)
Tony Henrich (3)
Torsten Weggen (2)
Vicenç Masanas (27)
Vincent Nguyen (3)
Vitaly Kozadayev (6)
Will Morgenweck (37)
Will Strohl (163)
William Severance (5)
Try Evoq
For Free
Start Free Trial
a Demo
See Evoq Live
Need More Information?