Magnus Rahl
Dec 9, 2013
(4 votes)

Replace SEO URL generation in EPiServer Commerce 7.5

EPiServer Commerce 7.5 offers two different approaches for routing to catalog content: The hierarchical route using the Name in URL property of the ancestor contents, and the SEO URL which has been fused with the Simple address system you know from EPiServer CMS. So the former will be on the format /catalog/category/subcategory/product and the latter a single URL segment. Which one is used when rendering links depends on how you register the catalog routes, see the routing article in the Commerce SDK / Developer Guide for more information.

By default the SEO URL is generated from the name of the content, with the “file extension” .aspx appended. To make the URLs unique per language branch, the language name may also be appended, to generate something like Red-Striped-Shirt-en.aspx.

Generating your own SEO URLs

The SEO URL generation is handled by the Mediachase.Commerce.Catalog.Data.UniqueValueGenerator class. You can override the generating bit in your own class:

   1: using System;
   2: using Mediachase.Commerce.Catalog;
   3: using Mediachase.Commerce.Catalog.Data;
   4: using Mediachase.Commerce.Shared;
   5: using System.Globalization;
   7: namespace EPiServer.Commerce.SampleMvc.Business
   8: {
   9:     public class ExtensionlessUniqueValueGenerator : UniqueValueGenerator
  10:     {
  11:         public ExtensionlessUniqueValueGenerator(ICatalogSystem catalogContext)
  12:             : base(catalogContext)
  13:         {
  14:         }
  16:         protected override string SuggestSeoUri(string name, string languageCode, int index, string duplicateUrl)
  17:         {
  18:             var slug = CommerceHelper.CleanUrlField(name);
  19:             if (String.IsNullOrEmpty(duplicateUrl))
  20:             {
  21:                 return slug;
  22:             }
  23:             return slug + "-" + index.ToString(CultureInfo.InvariantCulture);
  24:         }
  25:     }
  26: }

The overridden SuggestSeoUri method will be called repeatedly until it generates a unique value. The index parameter is incremented by one for each call, and the duplicateUri parameter is set to the value which was checked in the previous pass (it will be null in the first call). As you can see I completely ignore the languageCode parameter, which means two language versions may vary only by a number in the URLs (product-name-1 and product-name-2).

To make use of your implementation you need an initialization module to replace the configuration in the container:

   1: using EPiServer.Framework;
   2: using EPiServer.Framework.Initialization;
   3: using EPiServer.ServiceLocation;
   4: using EPiServer.Commerce.SampleMvc.Business;
   5: using Mediachase.Commerce.Catalog.Data;
   7: namespace EPiServer.Commerce.SampleMvc
   8: {
   9:     [ModuleDependency(typeof(EPiServer.Commerce.Initialization.InitializationModule))]
  10:     public class Initialization : IConfigurableModule
  11:     {
  12:         public void Initialize(InitializationEngine context)
  13:         {
  14:         }
  16:         public void Preload(string[] parameters)
  17:         {
  18:         }
  20:         public void Uninitialize(InitializationEngine context)
  21:         {
  22:         }
  24:         public void ConfigureContainer(ServiceConfigurationContext context)
  25:         {
  26:             context.Container.Configure(c => c.For<UniqueValueGenerator>().Use<ExtensionlessUniqueValueGenerator>());
  27:         }
  28:     }
  29: }
Dec 09, 2013


Jonathan Roberts
Jonathan Roberts Jan 17, 2014 01:06 PM

HI, How do you get the product URl from FIND search?

Apr 4, 2014 07:36 AM

Jonathan Roberts: Late answer, but when getting the content from Find, you can use the UrlResolver to get the Url using the content, or the content link.

Please login to comment.
Latest blogs
Content Delivery API – The Case of the Duplicate API Refresh Token

Creating a custom refresh provider to resolve the issues with duplicate tokens in the DXC The post Content Delivery API – The Case of the Duplicate...

David Lewis | Sep 29, 2022 | Syndicated blog

New Optimizely certifications - register for beta testing before November 1st

In January 2023, Optimizely is making updates to the current versions of our certification exams to make sure that each exam covers the necessary...

Jamilia Buzurukova | Sep 28, 2022

Optimizely community meetup - Sept 29 (virtual + Melbourne)

Super excited to be presenting this Thursday the 29th of September at the Optimizely community meetup. For the full details and RSVP's see the...

Ynze | Sep 27, 2022 | Syndicated blog

Preview multiple Visitor Groups directly while browsing your Optimizely site

Visitor groups are great - it's an easy way to add personalization towards market segments to your site. But it does come with it's own set of...

Allan Thraen | Sep 26, 2022 | Syndicated blog

The Report Center is finally back in Optimizely CMS 12

With Episerver.CMS.UI 12.12.0 the Report Center is finally re-introduced in the core product.

Tomas Hensrud Gulla | Sep 26, 2022 | Syndicated blog

Dynamic Route in ASP.NET Core When MapDynamicControllerRoute Does Not Work

Background Creating one of the add-on for Optimizely I had to deal with challenge to register dynamically route for the API controller. Dynamic rou...

valdis | Sep 25, 2022 | Syndicated blog