I wrote several posts about cross-site publishing in Sharepoint 2013 already (you may find them here). In this post I will describe the process of enabling SEO features on sites with cross-site publishing – important mechanism for public sites. Before to start I recommend to read useful document prepared by Waldek Mastykarz: Optimizing SharePoint Server 2013 websites for Internet search engines. It contains good overview of the related functionality. In my post I will go deeper and show how some of these features work internally.
So suppose we have common scenario for cross-site publishing: authoring site with published catalog and public site which is connected to this catalog. On public site there is target page which is used for displaying catalog items (it contains ContentBySearchWebPart or CatalogItemReuseWebPart or both). And we want to display title of the displayed item in browser title, which, as you probably know, has big sorting weight for search engines.
First of all let’s say a few words about how html title is displayed in Sharepoint (we will talk here about publishing sites). This information will be useful for understanding the concept, described later. First of all there is PageTitle control on the masterpage and content placeholder PlaceHolderPageTitle in it:
It may also contain some default content, but it is not important for us now. Particular page layouts may have Content control for this placeholder, and thus may override content in page title. Often they just contain FieldValue control for Title field, i.e. title specified in publishing page’s metadata will be used for browser title:
Returning to our example, target page for displaying catalog items is also regular publishing page created with some page layout. I.e. it also may have content for PlaceHolderPageTitle as shown above. But of course we don’t want it to display title of the page – because in this case it would mean that for all displayed items, browser title would be the same and would retrieved from metadata of details page itself, but not from search index with other item’s data. And here ContentBySearchWebPart.AddSEOPropertiesFromSearch property comes on the scene. With proper usage it allows to use data from search index for using e.g. in browser title (or description and keywords meta tags). As it often be however, documentation doesn’t help us a lot saying just that it:
Specifies properties to be used for search engines; these properties will optimize the crawlers and improve SEO.
But it didn’t say neither of how it does it nor how to properly configure it. Let’s fill this space by ourselves then.
First of all if you want to use SEO features, you need to enable Search Engine Optimization Feature (Site scope) on your site collection (we will check it later in this post), and at second you need to set AddSEOPropertiesFromSearch property to true for your web part. You can’t do it in UI, but it is possible to do by modifying webpart file:
Let’s analyze code of ContentBySearchWebPart in reflector and see how this property is used. It is used in 2 places: in OnLoad() and in OnQueryResolved() methods of the web part. Here is how it is used in OnLoad:
I.e. it just sets some search context IsSearchPage parameter to true. And that’s how it is used in OnQueryResolved:
Let’s check the code of PopulateSEOSearchContext() method used here:
SEOManagedProperties is private static collection populated in class constructor:
I.e. PopulateSEOSearchContext() checks for each row does it contain column defined in Item1 of tuples collection (like Title, Path, etc. – managed properties from search index), and if yes, stores values of these columns in search context with Item2 of corresponding tuple (e.g. for Title managed property it uses SeoPropBrowserTitle key). Ok, now let’s return to Search Engine Optimization feature and will see how these context values are used on the pages.
Search Engine Optimization feature adds a lot of functionalities for optimizing your web site for search engines. Among with other components it specifies the following delegate controls with AdditionalPageHead id for the site collection:
Using these controls you may significantly improve rank of your pages in search results. But it is not enough just activate this feature on the site collection. In order to really work, they should have some content when page is rendered. And in case of target page for displaying catalog items it is even more important, because they should contain different content depending on the current catalog item.
Let’s analyze last control SeoBrowserTitle. First of all its OnPreRender() method:
First of all it checks whether IsSearchPage search context parameter is set to true. If yes it calls SetRenderDelegate() method which replaces current content of the PlaceHolderPageTitle placeholder (in out case FieldValue control for Title field) with own RenderBrowserTitle() method:
And the rendering method itself:
Now remember that IsSearchPage search context parameter is set to true by ContentBySearchWebPart when AddSEOPropertiesFromSearch property is set to true. That’s how this property controls SEO controls on the page. In RenderBrowserTitle() method value of SeoPropBrowserTitle search context parameter is retrieved (which according to SEOManagedProperties collection corresponds to Title managed property in search index), and if it is not empty, it is written to html output.
We need also to mention that SeoBrowserTitle control overrides browser title also when IsSearchPage is false, but there are not-empty values in _Sys_Seo_PropBrowserTitle or SeoBrowserTitle fields of current page (see code above). These site columns are added also with Search Engine Optimization feature – see Optimizing SharePoint Server 2013 websites for Internet search engines document, mentioned in the beginning and its section 6.1 Using standard SEO columns within catalogs.
This is the final of this story. Hope that it was interesting and that it will help you in your work.