SharePoint 2010 introduces the SPShortcutIcon control which has been designed to add a favorites icon in the browser. For example, the standard SharePoint 2010 master page named v4.master uses the SPShortcutIcon control to to configure a favicon.ico file which is deployed in the IMAGES folder inside the SharePointRoot directory.
<SharePoint:SPShortcutIcon runat="server" IconUrl="/_layouts/images/favicon.ico" />
This control tag is what configures all unbranded sites in SharePoint 2010 with the standard three-headed orange favorites icon that screams "Look at me. I am a SharePoint site!".
Now imagine your are creating a custom branding solution for SharePoint 2010 and one of your requirements is to replace the out-of-box favorites icon with one of your own. Also imagine you have decided to deploy the favicon.ico file with your custom favorites icon to the Style Library of each participating site collection instead of deploying the file to the IMAGES folder inside the SharePointRoot directory. This design approach will provide greater deployment flexibility in a branding solution because you don't need to update the file system of the front end Web server.
Once you have added the custom version of the favicon.ico file into a location within the Style Library, you then configure your custom master page with an instance of the SPSharePointIcon control that looks like this.
<SharePoint:SPShortcutIcon runat="server" IconUrl="/Style Library/Wingtip/Images/favicon.ico" />
You find that this control tag works in some cases but not in others. More specifically, in your testing you find that this control tag only works when used in site collections that have been created at the root of their hosting Web application. For example, it works fine when the URL to the root of the site collection looks like this.
However, it doesn't work if the the URL to the root of the site collection looks like this.
The problem with the control tag you have just seen is that the favicon.ico file must be configured with a path relative to the root of the Web application. At this point your intuition might tell you that you can use an $SPUrl expression in the SPShortcutIcon control just like you do in other SharePoint controls. For example, you can use an $SPUrl expression along with the dynamic ~SiteCollection token for the name attribute of the CssRegistration control inside a custom master page to link to a CSS file inside the Style Library with a path relative to the root of the current Web application.
name="<% $SPUrl:~SiteCollection/Style Library/Wingtip/main.css %>"
Given the popularity of SharePoint branding techniques which use an $SPUrl expression containing the dynamic ~SiteCollection token, you might make a reasonable (yet incorrect) assumption that you can use the same approach when configuring the SPShortcutIcon control. For example, you might try and configure a control tag based on the SPShortcutIcon control like this.
IconUrl="<% $SPUrl:~SiteCollection/Style Library/Wingtip/Images/favicon.ico %>"
Unfortunately, this technique not yield the desired results. However, it's worse then that. This control tag causes a runtime error and if used in a custom master page it will bring down any site that uses it. The core problem we have here involves a .NET runtime exception caused by a type mismatch. An $SPUrl expression returns a value of type System.String type while the IconUrl property of the SPShortcutIcon control expects a value of type System.Uri. Here is a quick look at the SPShortcutIcon control as seen through the object browser in Visual Studio 2010.
At the end of the day, it's best just to abandon the SPShotcutIcon control for our scenario because it cannot give us what we want. After all, Microsoft really only designed and tested this control to work with favicon.ico files deployed inside the SharePointRoot directory which can always be configured with static paths which do not change across sites or site collections.
The good news creating the same output that is created by the SPShotcutIcon control isn't rocket science. All you really need to do is create a link element with a rel attribute and an href attribute and add it to the head section of the hosting HTML page.
<link rel='shortcut icon'
href='/sites/sales/Style Library/Wingtip/Images/favicon.ico' />
However, you don't want to add text like this to a custom master page because then you would be hard-coding it to only work inside a single site collection. Instead, you can add a set of ASP.NET literal controls along with an $SPUrl expression that includes the dynamic ~SiteCollection token. Here is a working sample that was first introduced to the SharePoint community in a blog by Joel Jeffery in November of last year.
<asp:literal runat="server" Text="<link rel='shortcut icon' href='"/>
<asp:literal runat="server" Text="<% $SPUrl:~SiteCollection/Style Library/Wingtip/Images/favicon.ico %>"/>
<asp:literal runat="server" Text="' />"/>
As it turns out, you can get rid of the asp:literal controls and just go with the $SPUrl expression which works just fine.
<link rel='shortcut icon'
href='<% $SPUrl:~SiteCollection/Style Library/Wingtip/Images/favicon.ico %>' />
By using this technique to add a custom favorites icon, you can create a custom branding solution that works on any site collection in any SharePoint 2010 farm regardless of whether it has been created at the root of the hosting Web application.