Safely Defining Multiple Sites in Sitecore

May 23, 2016 | Dave Evans

red orb with multicolored rays on black background

It’s easy to spin up multiple websites on a single Sitecore instance. You simply add site elements to the XML configuration file. The configuration of the site elements is fairly simple, but some non-documented requirements are necessary to reach this configuration. The first condition is that the rootPath attribute must be unique. The second condition is that the startItem attribute must be populated. If these requirements are not met, there are consequences that may not be obvious at first but will surely surface as you get further into site setup. If you’d like to avoid this, read on!

The site definition XML element has a variety of attributes which control the site’s behavior. The two that we are interested in here are rootPath and startItem. The rootPath is the full Sitecore path to the root item of the site. The item pointed to by the rootPath is not visible to front-end users of the site, nor are any ancestors of that item. The startItem is the homepage of the site—shown when the site is requested without further path information.

Suppose we have a tree like this:

Sitecore tree

A simple solution would be to create a config like this:

<site name="SiteOne" 
    rootPath="/sitecore/content" 
    startItem="/SiteHomeOne" 
    hostName=”www.siteone.com”  />
<site name="SiteTwo" 
    rootPath="/sitecore/content" 
    startItem="/SiteHomeTwo" 
    hostName=”www.sitetwo.com”  />

This seems sensible but violates our first requirement, namely, that the rootPath must be unique. It must be unique because site definition configurations that share a rootPath also share content paths. For instance, in the example tree above a user could view Site2 content from Site1 by visiting a URL like www.siteone.com/SiteHomeTwo/SectionLandingOne. Why? Because the rootPath is the root of the site, not startItem.

We may want to fix this by making the homepage the root of the site. So we configure the rootPath parameter to point to the homepage. But what to put in the startItem? Let’s leave it empty. Unfortunately, as we noted in beginning, startItem cannot be empty. Without a startItem specified, Sitecore will not be able to resolve the site correctly and so will generate all links with the full content path starting with /sitecore/content/. So what to do?

We have to create the tree like this:

another Sitecore tree

Now we can configure a unique rootPath and a startItem that is not empty:

<site name="SiteOne" 
    rootPath="/sitecore/content/SiteOne" 
    startItem="/SiteHomeOne" 
    hostName=”www.siteone.com”  />
<site name="SiteTwo" 
    rootPath="/sitecore/content/SiteTwo" 
    startItem="/SiteHomeTwo" 
    hostName=”www.sitetwo.com”  />

Unfortunately, there is still an issue with this configuration. The site’s own content can be viewed through the startItem path like this: www.siteone.com/SiteHomeOne/SectionLandingOne. In order to fix this we need to set up a Redirect rule to remove the SiteHomeOne element of the path.

<rule name="homepage path Redirect" stopProcessing="true">
    <match url="^SiteHomeOne/?(.*)" />
    <action type="Redirect" url="http://www.siteone.com/{R:1}" />
</rule>

With these configurations in place, links within each site generated by Sitecore will resolve to their proper site definition, and items will not be visible via the startItem path on either site. We’re almost where we need to be, but to get there we must take one last step—involve links generated via the Sitecore.Links.LinkManager.GetItemUrl method.

In the Sitecore configuration, there is setting named Rendering.SiteResolving. Its comment says, “while rendering item links, some items may belong to a different site. Setting this to ‘true’ makes LinkManager try to resolve the target site in order to use the right host name.” Inconveniently, the GetItemUrl(Item item) method does not respect the SiteResolving setting in the config. When using that method to generate a link to an item that is in another site, it returns the full Sitecore path to the item. Using our example content tree above, a link to SiteOne from within SiteTwo will appear in the form www.sitetwo.com/sitecore/content/SiteOne/SiteHomeOne/SectionLandingOne. In order to fix this, you must pass a Sitecore.Links.UrlOptions item to GetItemUrl. On that item, you must set the SiteResolving property to true. To make this easy, we created a helper method that retrieves the DefaultUrlOptions and sets SiteResolving to whatever it is set to in the config:

public UrlOptions GetDefaultUrlOptions()
{
  UrlOptions defaultOptions = LinkManager.GetDefaultUrlOptions();
  defaultOptions.SiteResolving = Settings.Rendering.SiteResolving;
  return defaultOptions;
}

Finally, your multi-site configuration will correctly resolve links, within sites and across sites. Congratulations; you have now safely defined multiple sites in Sitecore!

About the Author

Dave
Dave Evans

I'm a Senior Developer at TBG. I spend a lot of time in my garden too.

Leave A Reply

comments powered by Disqus