Persistent Site and Lang Query string

I’ve always wondered why the default link provider of Sitecore doesn’t carry over site and language parameters.  Quite often I’ve found myself in a situation where the official site resolution for a Sitecore site has to do with domain pattern matching.  This leaves us with a difficult time to test things in an authoring server or development server without the proper DNS names.

There is however a solution.  With a few minor tweaks to the default link provider.  The logic is simple, if there exists in the url currently an sc_site or sc_lang query string parameter then generate all links with these parameters too

Enter the SiteStaticLinkProvider.

	public class SiteStaticLinkProvider : LinkProvider
	{
		public override string GetItemUrl(Item item, UrlOptions options)
		{
			string urlString = base.GetItemUrl(item, options);
			if (HttpContext.Current?.Request.QueryString == null)
				return urlString;
			string[] urlParts = urlString.Split('?');
			NameValueCollection qs = null;
			NameValueCollection currentqs = HttpContext.Current.Request.QueryString;
			if (!string.IsNullOrWhiteSpace(currentqs["sc_site"]))
			{
				qs = HttpUtility.ParseQueryString(urlParts.Length >= 2 ? urlParts[1] : "");
				if (string.IsNullOrWhiteSpace(qs["sc_site"]))
				{
					qs.Add("sc_site", currentqs["sc_site"]);
				}
			}
			if (!string.IsNullOrWhiteSpace(currentqs["sc_lang"]))
			{
				if (qs == null)
					qs = HttpUtility.ParseQueryString(urlParts.Length >= 2 ? urlParts[1] : "");
				if (string.IsNullOrWhiteSpace(qs["sc_lang"]))
				{
					qs.Add("sc_lang", currentqs["sc_lang"]);
				}
			}
			if (qs != null)
			{
				return urlParts[0] + '?' + qs;
			}
			return urlString;
		}
	}

This provider is a good all purpose link provider because if there are no pertinent parameters present it will not do anything.

The end result here is that to test any site in a pre-prod environment you need to only add the sc_lang or sc_site parameter once and it will follow you around the site, making this very easy for content approvers.

Wire it up!

There’re a few options available to overwrite a link provider. You can add a new provider, then change the reference of the providers node to point to your new provider. Slightly simpler however is to straight up override the default sitecore provider like i’ve done below.

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
	<sitecore>
		<linkManager>
			<providers>
				<add name="sitecore">
					<patch:attribute name="type">[Namespace].SiteStaticLinkProvider, [Binary Name]</patch:attribute>
				</add>
			</providers>
		</linkManager>
	</sitecore>
</configuration>