Take the community feedback survey now.

Son Do
Mar 10, 2015
  3711
(1 votes)

Extend UniqueSeoGenerator to replace SEO URL generation in EPiServer Commerce 8.9

In EPiServer Commerce 7.5, we had Magnus Rahl's post about replacing SEO URL generation. And one more time from EPiServer Commerce 8.0 and above still support two different approaches for routing to catalog content. However, there are some improvements to make creating custom SEO easier, more flexible and increase performance.

By default the SEO URL is generated from content name, language branch name and “file extension” .aspx appended. SEO uri is look like “Tops-Tunics-LongSleeve-en.aspx” and with hierarchical route using the Name in URL property, it become /catalog/category/subcategory/ and URL segment.

And now, we can customize SEO URL by extending Mediachase.Commerce.Catalog.Data.UniqueSeoGenerator

Generating your own SEO URLs

The SEO URL generation is handled by the Mediachase.Commerce.Catalog.Data.UniqueSeoGenerator class. We can override the generating method:

Functions

Default value

UriExtension

“.aspx”

GenerateSeoUri(string name, string languageCode, bool includeRandomToken)

Default generate Uri like <name>-<randomToken>-<languageCode>.aspx
Sample: tops-tunics-longsleeve-en.aspx or tops-tunics-longsleeve-asdfghjk-en.aspx

GenerateUriSegment(string name, bool includeRandomToken)

Default generate Uri like <name>-<randomToken>
Sample: tops-tunics-longsleeve or tops-tunics-longsleeve-asdfghjk

GetRandomToken()

 

Sample extend class:

public class ExtendUniqueSeoGenerator : UniqueSeoGenerator
{
	protected override string UriExtension
	{
		get
		{
			// Default value is ".aspx"
			return ".html";
		}
	}

	public override string GenerateSeoUri(string name, string languageCode, bool includeRandomToken)
	{      
		// When extend UniqueSeoGenerator, Uri will become: tops_tunics_longsleeve_en.aspx or tops_tunics_longsleeve_en_asdfghjk.aspx
		return includeRandomToken
			? String.Format("{0}_{1}_{2}{3}", CommerceHelper.CleanUrlField(name), languageCode, GetRandomToken(), UriExtension)
			: String.Format("{0}_{1}{2}", CommerceHelper.CleanUrlField(name), languageCode, UriExtension);
	}

	public override string GenerateUriSegment(string name, bool includeRandomToken)
	{ 
		// When extend UniqueSeoGenerator, UriSegment will become: tops_tunics_longsleeve or tops_tunics_longsleeve_asdfghjk
		return includeRandomToken
			? String.Format("{0}_{1}", UrlSegment.GetUrlFriendlySegment(name), GetRandomToken())
			: UrlSegment.GetUrlFriendlySegment(name);
	}

	protected override string GetRandomToken()
	{
		var chars = "abcdefghijklmnopqrstuvwzyz1234567890";
		var random = new Random();
		var result = new string(
			Enumerable.Repeat(chars, 8)
					  .Select(s => s[random.Next(s.Length)])
					  .ToArray());
		return result;
	}
}

GenerateUri and GenerateUriSegment method will be called when data has the same Uri (or UriSegment) that is existed.To make use of your implementation you need an initialization module to replace the configuration in the container:

using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;
using EPiServer.Commerce.SampleMvc.Business;
using Mediachase.Commerce.Catalog.Data;
 
namespace EPiServer.Commerce.SampleMvc
{
    [ModuleDependency(typeof(EPiServer.Commerce.Initialization.InitializationModule))]
    public class Initialization : IConfigurableModule
    {
        public void Initialize(InitializationEngine context)
        {
        }
 
        public void Preload(string[] parameters)
        {
        }
 
        public void Uninitialize(InitializationEngine context)
        {
        }
 
        public void ConfigureContainer(ServiceConfigurationContext context)
        {
            context.Container.Configure(c => c.For< UniqueSeoGenerator>().Use<ExtendUniqueSeoGenerator>());
        }
    }
}
Mar 10, 2015

Comments

K Khan
K Khan Mar 10, 2015 10:21 AM

Thanks! :)

K Khan
K Khan Mar 12, 2015 11:43 AM

a related article for older versions
http://world.episerver.com/Blogs/Magnus-Rahl/Dates/2013/12/Replace-SEO-URL-generation-in-EPiServer-Commerce-75/

Please login to comment.
Latest blogs
Quiet Performance Wins: Scheduled Job for SQL Index Maintenance in Optimizely

As Optimizely CMS projects grow, it’s not uncommon to introduce custom tables—whether for integrations, caching, or specialized business logic. But...

Stanisław Szołkowski | Oct 8, 2025 |

Image Generation with Gemini 2.5 Flash

Gemini 2.5 Flash Image, nicknamed Nano Banana, is Google DeepMind’s newest image generation & editing model. It blends text‑to‑image, multi‑image...

Luc Gosso (MVP) | Oct 8, 2025 |

Automated Page Audit for Large Content Sites in Optimizely

Large content sites often face significant challenges in maintaining visibility and control over thousands of pages. Content managers struggle to...

Sanjay Kumar | Oct 6, 2025

Optimizely CMS Roadmap – AI, automation and the future of digital experiences

A summary of the roadmap for Optimizely CMS from the Opticon conference on September 30, 2025.

Tomas Hensrud Gulla | Oct 6, 2025 |