Home > Blogs > Optimizely > Overriding Handlers in Optimizely: The Power of Chaining Methods
Overriding Handlers in Optimizely: The Power of Chaining Methods
Ritesh Hadawale
Senior Software Engineer - Optimizely
June 27, 2025
Table of Contents
Introduction
When it comes to customizing front-end behavior in Optimizely’s Spire framework, developers often hit the same roadblock: how to inject or override logic without disrupting the entire codebase. That’s where the power of handler chaining comes in. With methods like addToChainBefore, addToChainAfter, and replaceInChain, Optimizely provides a structured, elegant solution to extend functionality without reinventing the wheel.
At Royal Cyber, we specialize in helping businesses get the most out of Optimizely’s flexible architecture. Whether you’re looking to inject custom business logic, extend user sessions, or tailor your site’s behavior without touching the core code, our team of certified experts ensures your enhancements are scalable, maintainable, and seamlessly integrated. In this blog, we’ll explore the top three methods to chain handlers — and show how these techniques can be game changers for your Optimizely project.
In this blog, we’ll focus on three smart ways you can override or extend the handler. There are multiple chain manipulation methods in Optimizely; they can be found in the (modules/client-framework/HandlerCreator.ts ) file, but we will focus on these three main chain manipulation methods that are commonly used:
- addToChainBefore
- addToChainAfter
- replaceInChain
Let’s go through each of them one by one, but before that, let’s understand what handlers are and why we use them.
Discover Our Optimizely Solutions Today!
What are Handlers in Optimizely?
Before diving into the technical definition, let’s understand the concept of handlers with a real-life example. Imagine you’re at the airport and going through the security check. You pass through several checkpoints:
- ID check
- Baggage scan
- Body scan
- Final boarding pass check
Imagine each step as a handler. Similarly, Process moves from one to the next one with the Optimizely chain pattern:
- We can add a step before
- We can add a step after
- We can replace the step
We can add a step before baggage scan, let’s say temperature check, addToChainBefore, or we can replace the Body Scan with any other Step, and so on. Similarly, handlers are organized in a specific order, and they get executed after one another. Instead of patching your code, you can modify these chains using a few helper methods.
ReplaceInChain: Fully Override a Handler Function
This is the easiest way to take full control of what the handler is doing
When You Should Use:
- We need to change the logic of an existing handler completely.
- The default logic doesn’t meet your requirements.
Example:
export const CheckExpirationDateUpdate: HandlerType = props =>; {
const session = props.getState().context.session;
const now = new Date();
if (session?.expirationDate &;&; new Date(session.expirationDate) <; now) {
console.log("Session expired");
// Add any extra logic here, e.g., notify user or logout
}
};
replaceInChain(chain, CheckExpirationDate, CheckExpirationDateUpdate);
In this example, we’re replacing the CheckExpirationDate handler with our custom logic. The original logic will no longer run — it’s completely overridden.
AddToChainBefore: Inject Logic Before an Existing Handler Function
A prominent way for injecting any logic before the actual handler runs
When You Should Use:
- You want to change any information before the next step is executed
- You need to keep track of what is happening.
Example:
export const SendDataLayer: HandlerType = props =>; {
const { session } = getSession(props.getState()) || {};
const accountType = session?.properties?.isBusinessAccount?.toLowerCase() === "true" ? "Company": "Personal";
userLoggedOut({
event: "user_logged_out",
account_type: accountType,
user_id: props.getState().context.session?.userName,
});
};
addToChainBefore(chain, DeleteSession, SendDataLayer);
In this example, SendDataLayer is inserted before the DeleteSession step, allowing us to track user logout just before the session is destroyed.
AddToChainAfter: Run Logic After an Existing Handler Function
To post-process results or append logic once a handler has done its job, use this.
When to Use:
- You want to log the result, track analytics, or trigger any action after existing logic is executed.
- You want to extend and not replace the handler
Example:
Log the enriched product:
export const AddAccountSendDataLayer: HandlerType = props =>; {
if (props.apiResult.successful) {
userCreated({
event: "user_created",
account_type: "Personal",
user_id: props?.apiResult?.result?.userName ?? props?.parameter?.email
})
}
};
addToChainAfter(chain, AddAccount, AddAccountSendDataLayer);
In this example, the AddAccountSendDataLayer handler runs after the default AddAccount logic finishes — giving you a clean place to hook in tracking or logging without interfering with the core functionality.
Important Notes
- Always import the chain from the same file where the original handler is defined.
- Make sure you import the specific handler (e.g., DeleteSession, AddAccount, etc.) from the original source file — the one you’re trying to extend, replace, or modify. This is crucial because the chaining only works if you target the correct reference.
- Then, write your custom handler using the correct chaining method like this:
replaceInChain(chain, ExistingHandler, CustomHandler);
addToChainBefore(chain, ExistingHandler, CustomHandler);
addToChainAfter(chain, ExistingHandler, CustomHandler);
These patterns help you avoid rewriting logic and keep your customizations clean and modular.
Which One Should You Use?
| Use Case | Method |
|---|---|
| Replace the original logic | replaceInChain |
| Insert logic before handler | addToChainBefore |
| Run logic after handler | addToChainAfter |
These methods let you control exactly where your code runs in Optimizely’s logic, without needing to rewrite whole files or play with existing Out-of-The-Box (OOTB) code. By doing this, you’re making sure your code runs in the right place at the right time.
Conclusion
Optimizely’s handler chaining pattern empowers developers to introduce or modify functionality without compromising existing logic — a vital feature for modern, agile eCommerce implementations. From overriding default behavior, extending functionality, or inserting custom tracking steps, methods like replaceInChain, addToChainBefore, and addToChainAfter allow users to do so efficiently.
At Royal Cyber, we help enterprises implement robust, high-performance Optimizely solutions by leveraging these best practices. From deep customizations to enterprise-grade integrations, our Optimizely-certified team ensures that every customization aligns with your business goals, without creating any technical debt. Connect with us to learn how we can help you unlock Optimizely’s full potential and build innovative digital experiences that are powerful and future-ready.
Author
Poonam Chandersy
Talk To Our Experts
Recent Blogs
- Websites used to be something you built once and basically forgot about. That doesn’t work …Read More »
- Learn how to plan an Optimizely CMS 13 upgrade with .NET 10, Optimizely Graph, Visual …Read More »
- Learn how AI meeting notes automate summaries, action items, and insights from video meetings using …Read More »






