IIS7 Extensionless Urls, SEO and Kentico 5.0

My previous post on this subject only went so far. It focused solely on the usage of extensionless urls with Kentico but stopped short of full SEO compliance because of problems experienced when trying to integrate Kentico SEO settings with the IIS7 rewrite module. This post completes the by getting the SEO settings fully implemented as well.

Base System Requirements

IIS 7.x with .net 3.5 SP1 on a Windows Vista/7 dev machine or Windows 2008 (R2) server. Tested with Kentico 5.0

IIS 7 Rewrite Module is great!

I’ve found it pretty hard to get Kentico to look at the IIS7 Rewrite module, i think they see it has conflicting with the Kentico one, but i think it complements and extends it.

For example, if you want to have powerful regular expression powered 301 redirects added when upgading an existing site, it’s much easier to do this with the IIS7 Rewrite module than within Kentico.

Install the marvellous IIS 7.0 URL Rewrite Module (version 2.0 just released in March 2010)
Get it here: http://www.iis.net/downloads/default.aspx?tabid=34&g=6&i=1692
Learn about it here: http://learn.iis.net/page.aspx/460/using-url-rewrite-module/

IIS SEO Toolkit is great!

The IIS SEO Toolkit allows you to analysis many aspects of your sites quality and performance with particular focus on SEO weaknesses, which are shown up as ‘violations’ and ‘warnings’. You will find that if you are using Kentico that implementing the guidelines in this post will dramatically reduce the number of those you will get when running the tool. Note that anyone can run this toolkit as long as they are running Windows and it can run against local and remote websites.

Get it here: http://www.iis.net/expand/SEOToolkit

Configuring Extensionless Urls and Kentico SEO Settings

In the AppSettings section of your web.config,  set the following setting to ensure Kentico will not write out form actions which end in .aspx (which it does by default).

CMSUseExtensionOnPostback = false

Next, make sure Kentico is configured for extensionless urls and has the appropriate SEO settings configured as follows:

  • Site Manager > Settings > URLS and SEO >
  • Ensure the ‘Friendly URL Extensions’ value is blank
  • Ensure the ‘Files friendly URL Extensions’ value is ‘/’ (slash) *
  • Ensure the ‘Use Urls With Trailing Slash’ value is set to ‘Always use URLs with trailing slash’
  • Ensure the ‘Redirect invalid case URLs to their correct versions’ value is set to  ‘Redirect all requests to lower case’

* Kentico treats a blank Files Friendly Extension value to mean it should use the extension of the file, so you would get /getattachment/{guid}/file.jpg for example. This is a little confusing because by default .net does not process these extensions so 404s result all over the place. Adding the slash means that your files have the url /getattachment/{guid}/file.jpg/ which will get processed fine. If you really want you can leave it blank and configure IIS to process all the relevant static extensions you require for files, but i find that more trouble than it’s worth and find the slash based file url to be fine from an SEO perspective.

Now all you need to do now is apply the rewriting rules within the web.config, utilising the IIS Rewrite Module’s capabilities. The great thing is you don’t need to do anything within IIS, you can manage everything within the web.config and simply deploy it out to target servers without worrying about any additional configuration.

The first rule below ensures that a trailing slash is added to all url requests unless they already have one or have an extension already for whatever reason (e.g. asmx ajax requests)

The second rule rewrites the trailling slash url to an aspx request to be processed by Kentico. (Note: The addition of the trailing slash on the rewritten url is to stop Kentico trying to append the trailing slash to the rewritten url, which i noted in my previous post).

The third rule is a special one for processing the home page request and rewriting this as if it were a trailing slash request.

Note that all of this happens before requests reach Kentico.
[sourcecode language=”xml”]
<rule name="EnforceTrailingSlash">
<match url="^(.*)$" ignoreCase="false" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{URL}" negate="true" pattern="(.*)/$" />
<add input="{URL}" negate="true" pattern="(.*).(.*)$" /> />
<action type="Redirect" url="{R:1}/" redirectType="Permanent" />

<rule name="TrailingSlashToAspx">
<match url="^(.*)/$" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_URI}" negate="true" pattern="/cmsdesk/(.*)$" />
<add input="{REQUEST_URI}" negate="true" pattern="/cmssitemanager/(.*)$" />
<action type="Rewrite" url="{R:1}.aspx/" />

<rule name="HomepageToAspx">
<match url="^$" />
<action type="Rewrite" url="default.aspx/" />
Enforcing lower case urls

Kentico does not enforce lower case urls when documetns are added or updated. This is important because otherwise urls will get rendered in mixed case and then 301 redirects will be performed to get to the lower case versions. It is hoped this is addressed in a future version of Kentico, but in the mean time we can use the Kentico custom event handler capability to deal with this ourselves.

You will need to check out the Kentico event handler documentation to see how to set up custom event handlers for your project. Here is teh code to add to the CustomTreeNodeHandler to ensure that when anything is added or updated, the NodeAlias propety (and therefore the url) is lower-cased. Note that doing this in OnBeforeInsert didn’t work ffor inserts or some reason, so i found the only way to get it to work was to update the node straight after it was inserted. A double call to the database i guess, but not too bad, Kentico are investigating.
[sourcecode language=”csharp”]
public override void OnAfterInsert(object treeNodeObj, int parentNodeId, object tree)
// ensure node alias is lower cased
TreeNode node = (TreeNode)treeNodeObj;

public override void OnBeforeUpdate(object treeNodeObj, object tree)
// ensure node alias is lower cased
TreeNode node = (TreeNode)treeNodeObj;
node.NodeAlias = node.NodeAlias.ToLower();

We now have Kentico 5.x solutions with IIS7 configured to support the following:

  • Extensionless urls for all page node and attachment requests
  • Extensionless url support for postback urls
  • Trailing slash enforcement for all urls
  • Lower case enforcement for all urls

Taken all together this should mean that you have a best practice SEO Kentico website.