The Salla Component Hooks System is a JavaScript API that lets developers work with Salla’s web components at runtime, like changing the UI, intercepting validation, and tracking lifecycle events. It does all this without touching core theme code or worrying about when scripts load.
Timing Independent
Register hooks before or after components load. The system handles both cases automatically.
Whitelist Secured
Only approved hook names are accepted. Unauthorized registrations are blocked with a console warning.
Error Isolated
Errors in your callback never crash the core component. Partner code fails safely.
No Duplicates
Components are tracked in a Set, the same element never triggers your hook twice.
Template Hooks vs. Component Hooks | What's the Difference?#
Salla provides two distinct hook systems. Knowing which one you need saves a lot of confusion: | Template Hooks | Component Hooks |
|---|
| Syntax | {% hook 'head:start' %} (Twig) | Salla.hooks.registerHook(...) (JavaScript) |
| Side | Server-side | Client-side (runtime) |
| Purpose | Inject HTML into page template slots | Interact with rendered web components |
| Used in | .twig theme files | in scripts / JS integrations |
If you are editing .twig template files, you want the Template Hooks article. If you are writing a partner script or JavaScript integration, you are in the right place. 📙 What You'll Learn#
How It Works#
The hooks system lives at Salla.hooks and is built around three internal structures:
Store
a Map of registered callbacks, keyed by
component tag and hook name.
Whitelist
a Map that defines exactly which
hook names are allowed per component tag.
Component History
a Map that records every
component element that has loaded on the page, enabling late registration.When a Salla component mounts, it calls Salla.hooks.registerComponent(tag, element), which triggers any existing componentDidLoad callbacks and stores the element in history. This allows future hook registrations to access it retroactively.
Always wrap your hook registrations inside Salla.onReady() to guarantee the Salla SDK is fully initialized before your code runs.
Registering a Hook#
| Parameter | Type | Required | Description |
|---|
tag | string | ✅ | The component tag name (e.g. 'salla-add-product-button') |
hookName | string | ✅ | The hook to subscribe to (e.g. 'componentDidLoad', 'validate') |
callback | Function | ✅ | Runs when the hook fires. Receives a context argument depending on the hook. |
options | object | ❌ | { priority: number, once: boolean } — both optional |
Returns an unsubscribe function. Call it to cleanly remove your hook.
Available Components & Hooks#
| Hook Name | When Called | Context Received | What You Can Modify |
|---|
componentDidLoad | When the button component finishes rendering | element (HTMLElement) | The element and its children |
validate | During the add-to-cart validation flow | { isValid, productId, component } | ctx.isValid to block or allow the action |
Properties Reference#
When your callback receives a component object, either directly as element in componentDidLoad or via ctx.component in validate, you have access to the full component instance.The following properties are available on salla-add-product-button:When you receive { isValid, productId, component } in the validate hook, modifying ctx.isValid affects whether the add-to-cart action is allowed to proceed. Be deliberate.
Late Registration Support#
This is one of the most powerful aspects of the system. Your script does NOT need to load before the components.In a classic event-driven model, if a component fires its load event before your script is ready, you miss it entirely. This forces brittle load-order dependencies.
Hook Options: Priority & Once#
The optional fourth argument to registerHook() accepts two options.Controls execution order when multiple callbacks are registered for the same hook. Higher values run first. Default is
0.
Removing a Hook#
You have three ways to remove hooks depending on how granular you need to be.Via the Returned Unsubscribe Function
The cleanest approach, store the return value of
registerHook() and call it when done.
Real-World Use Cases#
The full integration pattern. Listens for a
Product Viewed analytics event, then registers both a UI hook and a validation hook for that specific product.
Security | The Whitelist System#
Every call to registerHook() is validated against the whitelist before any callback is stored. Two checks must pass:1.
Is the tag in the whitelist?
2.
Is the hook name allowed for that tag?
If either check fails, the registration is ignored and a warning shows in the browser console. A no-op function is returned instead of a real unsubscribe handle, so your code won’t break, but the hook won’t do anything.