All Articles

Customize VaryBy Caching in Sitecore 9.3

Sitecore provides caching to be configured at the rendering levels and the page levels.

We get various options to vary cache for the components. The options are as follows:

  1. Vary By Data
  2. Vary By Parm
  3. Vary By Device
  4. Vary By Login
  5. Vary By Query String
  6. Vary By User
  7. Clear on Index Update

Rendering Cache Options

We had a specific requirement where we had to vary the cache based on, if a custom logo is selected for a particular page.

As the Logo is fetched by the page item which is not the datasource for the rendering, we cannot use VaryByData as an option.

The solution to this is to override the GenerateCacheKey processor.

  1. Add a class named GenerateCustomCacheKey with the below code.
using Sitecore.Mvc.Pipelines.Response.RenderRendering;
using Sitecore.Mvc.Presentation;

namespace HabitatHome.Foundation.Caching.Pipelines
{
	public class GenerateCustomCacheKey : GenerateCacheKey
	{
		public GenerateCustomCacheKey(RendererCache rendererCache) : base(rendererCache)
		{
		}
		protected override string GenerateKey(Rendering rendering, RenderRenderingArgs args)
		{
			var cacheKey = base.GenerateKey(rendering, args);
			var customLogo = (Sitecore.Data.Fields.ReferenceField)Sitecore.Context.Item.Fields["Custom Logo"];
			if(customLogo != null && customLogo.TargetItem != null && rendering.Caching.VaryByData)
			{
				cacheKey += "_#logo:" + customLogo.TargetID.ToShortID();
			}
			return cacheKey;
		}
	}
}
  1. Add the below patch config file to your project.
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
	<sitecore>
		<pipelines>
			<mvc.renderRendering>
				<processor patch:instead="processor[@type='Sitecore.Mvc.Pipelines.Response.RenderRendering.GenerateCacheKey, Sitecore.Mvc']"
								type="HabitatHome.Foundation.Caching.Pipelines.GenerateCustomCacheKey, HabitatHome.Foundation.Caching" resolve="true" />
			</mvc.renderRendering>
		</pipelines>
	</sitecore>
</configuration>

Note that the attribute ‘resolve=true’ is included in the patch file, if not included we would get an error that the class does not have a Parameter-less Constructor.

We are also checking VaryByData to make sure that the configuration can be modified later if required.

Please let me know in the comments if you have any questions/suggestions.

Happy Sitecoring!