Where can you “hook” into an SFRA request or controller?

Have you ever wondered how Salesforce Commerce Cloud, especially SFRA (Storefront Reference Architecture), handles the rendering of pages based on controllers and routes?

It’s like embarking from point A to point B, with controlled detours and sudden stops. This blog will explore how SFRA allows us to navigate these situations and the various options available at different locations.

Let’s dive in!

Global Hooks

Before we discuss the SFRA specifics, let’s start with some global options that allow us to execute code for any request (SFRA or not).

For the technical details, please read this blog post by Johnny Tordgeman.

onRequest

The onRequest hook in SFCC allows you to intercept and modify an incoming HTTP request before the system processes it.

This hook is commonly used for session validationrequest validation, or custom logging tasks.

onSession

The onSession hook is a server-side hook executed at the beginning of each new session. This hook allows you to perform custom logic or set session attributes before the session is initialised.

It can be used to customise the session behaviour (like plugin_slas), such as setting default values, checking for certain conditions, or performing any necessary setup before the session is fully established. 

SFRA Routes?

A screenshot of the Home.js controller file of the standard SFRA. It contains two routes: Show and ErrorNotFound.
The "home.js" controller file of SFRA

Before we get started, we need to ensure we are on the same page on what a “route” is.

In the context of SFRA (Storefront Reference Architecture) of SFCC (Salesforce Commerce Cloud), a controller route is a mapping between a URL and a specific controller function.
When a user navigates to a specific URL within the SFRA storefront, the controller function, a key element of the SFRA architecture, handles the request and generates the appropriate response (usually ISML or JSON). 

The standard available options, and the most common ones, are:

  • GET
  • POST

These will serve as the ‘base route’, the starting point of our project. But remember, this is just the beginning. We have the power to extend and customize this base route of SFRA, as we’ll discover in the options outlined in this blog post.

SFRA Server functions to extend and replace

home show sfra controller
The standard Home-Show controller logic visualised
				
					Cartridge path: plugin_custom:app_storefront_base
				
			

server.prepend()

The `server.prepend` function adds a middleware function to the beginning of the route stack. This allows you to execute code before the base (app_storefront_base) processing begins.

Here’s a simple example of how you can use `server.prepend` with the homepage function:

				
					server.prepend('Show', function (req, res, next) {

 // Your code here will be executed before the app_storefront_base

 next();
});
				
			
SFRA prepending of Home-Show
Visualising what "prepending" does in a single route (Home-Show)

server.append()

The `server.append` function adds a middleware function to the end of the route stack. This allows you to execute code after the base (app_storefront_base) processing finishes.

Here’s a simple example of how you can use `server.append` with the homepage function:

				
					server.append('Show', function (req, res, next) {

 // Your code here will be executed after the show function in app_storefront_base

 next();
});
				
			
SFRA appending of Home-Show
Visualising what "appending" does in a single route (Home-Show)

server.replace()

The `server.replace` function replaces the entire route stack up until that point. This allows you to replace code in the base (app_storefront_base) fully.

Here’s a simple example of how you can use `server.replace` with the homepage function:

				
					server.replace('Show', function (req, res, next) {
    var Site = require('dw/system/Site');
    var PageMgr = require('dw/experience/PageMgr');
    var pageMetaHelper = require('*/cartridge/scripts/helpers/pageMetaHelper');
    
    pageMetaHelper.setPageMetaTags(req.pageMetaData, Site.current);
    
    var page = PageMgr.getPage('homepage');
    
    if (page && page.isVisible()) {
        res.page('homepage');
    } else {
        res.render('home/homePage');
    }
    
    next();
});
				
			
SFRA replacing of Home-Show
Visualising what "replacing" does in a single route (Home-Show)

SFRA Route Hooks

The options explained above already give you quite a bit of flexibility. But what if I told you there is even more to come? The route itself also exposes a few “events” in which we can hook into:

  • route:Start: Executes at the start of the route, before any middleware defined using “server.*”
  • route:BeforeComplete: Executes after all route middleware is finished but before the “route:Complete” event.
  • route:Complete: The final event, after everything else.
  • route:Step: Executed between each route middleware.
  • route:Redirect: Executed when a “res.redirect()” is executed.
				
					server.replace('Show', function (req, res, next) {
     this.on('route:BeforeComplete', function (req, res) { 
        var viewData = res.getViewData();

       // Your custom logic, executed at the end of the route
    });
    
    next();
});
				
			

Bringing it all together

sfra home route with all extension points 2
Bringing all of the options together!

Multiple Cartridges

The cartridge path influences the order in which SFRA middlewares are executed.

Cartridges higher up in the path are given precedence over those lower down. This means that the middleware in cartridges at the beginning of the path will be executed before those in cartridges further down the path. 

New to the concept of “cartridge path”? Have a look at this trail!

A digital drawing of different roads that seem to have been "modified", creating an odd structure.

Table of Contents

Facebook
Twitter
LinkedIn