Try our conversational search powered by Generative AI!

Make Episerver prioritize CMS pages over Commerce catalog-nodes


I'm currently working on a project that uses Episerver CMS and Commerce. We've run into a situation where we would like to show a regular CMS page on a url path that normally leads to a Commerce catalog node. At the moment, the commerce catalogs seems to have presedence over cms content.

Current behaviour: /new-york/pizza -> Would currently resolve a catalog node from EPI Commerce and render this according to our catalog controller.

However, we would like to create a Episerver CMS page with the same URL and show a regular standard page. Currently, when doing this the catalog content is rendered
and the CMS page is ignored.

Desired behaviour: /new-york/pizza -> CMS Page and commerce content exists at this path. But we want render the CMS page.

Is it possible at any place during the routing lifecycle to check if the url can resolve a CMS page and then do that instead of resolving the commerce content? Bascially ensure that if a CMS page exist at the url it has presedence over the commerce content.

Thanks in advance!

Jul 02, 2019 9:32

I haven't tried it, but you probably can listen to Routes_Registered event to register Catalog route. That way the Catalog route will be registered last and be overridden by the cms route. Might not work, but it is easy to at least try.

Jul 02, 2019 10:55

Thanks for the response Quan.

To be honest I'm not sure where to register these events listeners and exactly how I register the catalog routes. 

    public class RegisterCustomContentRouteInitialization : IInitializableModule
        public void Initialize(InitializationEngine context)
            EPiServer.Global.RoutesRegistered += RoutesRegistered;

        private void RoutesRegistered(object sender, EPiServer.Web.Routing.RouteRegistrationEventArgs e)
          // Do something here, but what, exactly?

Is this what you mean when you say listen to the Routes_Registered event? And would I check the sender object or e argument and then register a route?

Jul 02, 2019 11:11

You can look for CatalogRouterHelper usage in your code which should be registering the route, then move it here

Jul 02, 2019 11:43

Thank you, Quan!

I managed to register the catalog routes after the CMS content routes were registered but it didn't produce the desired result. I'm all ears if you have any other alternatives that may solve this.

Edited, Jul 02, 2019 12:26

I would suggest to try this out  so you can see the order of routes registered. if they are as expected (i.e. the catalog route is registered last) then ... we need to think of something else 

Jul 03, 2019 12:44

When I debug during startup I hit the breakpoint for registering the CMS routes before the Commerce routes but in the developer tools they still end up under the Commerce routes. Is this order saved to a database perhaps, would I need to clear it before running the route registration again?

Jul 03, 2019 13:25

No the routes are registered in memory and not saved in DB. That is very strange ... 

Jul 03, 2019 13:35

In my experience the CMS pages has the higher priority in these routing cases... if you unpublish/expire the commerce node do you end up on the cms page then?

Jul 03, 2019 16:49

Thank you for the suggestion Erik. If I expire commerce node I get a 404. However other pages that does not match a commerce node renders correctly.

This is my CMS page structure

--- /pizza -> Also matches a commerce node. Gives 404 when the commerce node is expired / unpublished. Prioritizes commerce node if it is active.
--- /burgers -> Does not match commerce node. Renders cms page correctly.

Jul 03, 2019 17:56

All right, so I finally found a solution. Based on Quans suggestion to register the commerce routes last I instead wait for all routes to be registered and manually switch out the "pages" route handler to a lower order/index in the RouteCollection list (giving it higher priority). This seems to produce the desired result. Are there any drawbacks of this that we should be aware of? As you might have noticed I'm not completely on top of Episerver internals.

  public class SiteInitialization : IConfigurableModule
        public void Initialize(InitializationEngine context)
            // Setup code...

            EPiServer.Global.RoutesRegistered += OnRoutesRegistered;

        private void OnRoutesRegistered(object sender, RouteRegistrationEventArgs e)
            // This method will wait until all routes are registered in-memory by Episerver
            // Then it will find the route handler for regular EpiServer CMS pages move it to a lower order than the commerce pages, giving it higher priority
            // if a cms and a commerce page exists at the same url.
            var defaultRoute = e.Routes
                .Select(r => r as DefaultContentRoute)
                .Where(x => x != null)
                .First(x => x.Name.Equals("pages", StringComparison.InvariantCultureIgnoreCase));

            var indexOfPagesRoute = e.Routes.IndexOf(defaultRoute);

            e.Routes.Insert(10, defaultRoute);
Jul 04, 2019 9:57
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.