Salla.hooks and is built around three internal structures:Map of registered callbacks, keyed by component tag and hook name.Map that defines exactly which hook names are allowed per component tag.Map that records every component element that has loaded on the page, enabling late registration.Salla.hooks.registerComponent(tag, element) internally. This fires any already-registered componentDidLoad callbacks for that element and adds it to the history — so any future registrations can also reach it retroactively.Salla.onReady() to guarantee the Salla SDK is fully initialized before your code runs.| 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 |
unsubscribe function. Call it to cleanly remove your hook.salla-add-product-button| 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 |
salla-products-list| Hook Name | When Called | Context Received | What You Can Modify |
|---|---|---|---|
componentDidLoad | When the list component finishes rendering | element (HTMLElement) | The element and its children |
beforeBuildListUrl | Before the product fetch URL is built or pagination cursor is consumed | { component, url } | ctx.url to rewrite the request URL |
componentDidLoad only:| Component Tag | Description |
|---|---|
salla-product-options | Product options selector |
salla-products-slider | Horizontal product slider |
salla-hook | Internal theme slot mounting component |
salla-scopes | Scopes / permissions component |
salla-user-menu | User account menu |
load event before your script is ready, you miss it entirely. This forces brittle load-order dependencies that are hard to maintain.componentDidLoad hook, it immediately invokes your callback for every component of that type that has already loaded, then continues firing for future ones.salla-add-product-button element renders on the page. It internally calls registerComponent(), fires any already-registered componentDidLoad callbacks, and adds itself to the component history.Salla.hooks.registerHook('salla-add-product-button', 'componentDidLoad', cb).salla-add-product-button element on the page.salla-add-product-button elements that load after your registration will also trigger your callback normally going forward.registerHook() accepts two options.registerHook() and call it when done.component object — either directly as element in componentDidLoad or via ctx.component in validate — you have access to the full component instance.salla-add-product-button:ctx.isValid in the validate hook directly affects whether the add-to-cart action proceeds. Be deliberate about what you change.registerHook() is validated against the whitelist before any callback is stored. Two checks must pass:_whitelist Map in /packages/twilight/src/lib/hooks.js. See Requesting New Hooks in the Overview article for the full process.| Next Step | Description |
|---|---|
| Hooks Overview | Go back to understand how Template and Component Hooks connect |
| Template Hooks | Explore server-side Twig hooks for theme developers |