Skip to content
Twilight React Playground
ثيم رائدaren

useHook

hookBeginnerserverbrowserlive demo

Registers a slot handler for as long as the calling component is on screen, and clears that slot name when it goes away.

import { useHook } from '@salla.sa/twilight-theme-engine/hooks/useHook';

In plain words

useHook(name, handler) is the component version of hookRegistry.register: it fills a slot from inside a component, and empties it again when the component is removed from the page (unmounted).

It returns nothing. It does not read a slot; to show a slot, render a HookSlot.

Signature

function useHook<T = Record<string, unknown>>(
  name: string,
  handler: HookHandler<T>,
  priority?: number  // default 50
): void

Try it live

Two components each call useHook() for the same slot, and render nothing themselves. The dashed box is the slot.Try this: with both switched on, turn Banner off: the Badge disappears too, although its component is still mounted.
Storefront canvas · en · LTR
Nothing registered.
Controls
Mount Banner
Mount Badge
What a theme writes
import { useHook } from '@salla.sa/twilight-theme-engine/hooks/useHook';

export function SaleBanner() {
  useHook('playground:use-hook', () => <p className="banner">{'Summer sale ends Friday'}</p>);
  return null; // the content appears wherever <HookSlot name="playground:use-hook" /> is
}

Example

app/components/cart/FreeShippingNotice.tsx
import { useHook } from '@salla.sa/twilight-theme-engine/hooks/useHook';

export function FreeShippingNotice({ threshold }: { threshold: number }) {
  // A name of your own: on unmount, every handler under this name is cleared.
  useHook('theme:cart.notice', () => <p className="notice">Free shipping over {threshold} SAR</p>);
  return null;
}

// Elsewhere: <HookSlot name="theme:cart.notice" />

How it behaves

  • It registers in an effect, so only in the browser: the server HTML never contains the content, and the slot shows its fallback until hydration.

  • The newest handler is kept in a ref, so an inline arrow function does not re-register on every render. It re-registers only when name or priority changes.

  • The cleanup calls hookRegistry.clear(name).

Gotchas

  • Unmounting clears every handler under the name, not only this component's: the engine's defaults, the theme's registrations and other components' useHook calls. Used on HookName.BODY_END, unmounting removes TwilightBundles and the fast-checkout script. Only use names of your own.

  • Changing priority clears the name before registering again, with the same effect.

  • A slot does not re-render when your component does. The handler reads the latest props through its ref, but a slot elsewhere on the page shows the new value only the next time it renders.

  • docs/18-hooks-api.md shows const hookData = useHook('product:form.start') to "access a registered hook handler". That call has no handler and returns nothing: the signature is (name, handler, priority) and the result is void.

Related

Source and docs