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

HookName and hook handler types

enumAdvanced

The hook slot names and handler types, from a subpath that loads no React code and registers no default handlers.

import { HookName, HookHandler, HookHandlers, HookDefinition } from '@salla.sa/twilight-theme-engine/types/hooks';

In plain words

Slot names such as header:start, and the types of the functions you place in slots, belong to the engine's hook system. This import path gives you only those: the HookName list and three types, without the hooks, components and default slot content that @salla.sa/twilight-theme-engine/hooks brings along.

Use it in a file that only needs the names, such as a list of the slots your theme fills. Each name is explained on the HookName page.

Signature

enum HookName {
  BODY_START = 'body:start',  BODY_END = 'body:end',  BODY_INNER = 'body:inner',
  HEAD_START = 'head:start',  HEAD_END = 'head:end',  HEAD_INNER = 'head:inner',
  HEADER_START = 'header:start',  HEADER_END = 'header:end',
  FOOTER_START = 'footer:start',  FOOTER_END = 'footer:end',
  PRODUCT_FORM_START = 'product:single.form.start',
  CART_SUMMARY_START = 'cart:summary.start',
  // …26 members in all
}

type HookHandler<T = Record<string, unknown>> = (context: T) => ReactNode;

type HookHandlers = Record<
  string,
  HookHandler | Array<{ priority?: number; handler: HookHandler }>
>;

interface HookDefinition {
  id: number;
  handler: HookHandler;
  priority: number;
}

Example

app/hooks/slots.ts
// app/hooks/slots.ts: the slots this theme fills, importable from any file.
import { HookName } from '@salla.sa/twilight-theme-engine/types/hooks';

export const PROMO_SLOTS = {
  top: HookName.HEADER_START,
  bottom: HookName.FOOTER_START,
  cart: HookName.CART_SUMMARY_START,
} satisfies Record<string, HookName>;

export type PromoSlot = keyof typeof PROMO_SLOTS;

// app/hooks/promo.tsx
import { hookRegistry } from '@salla.sa/twilight-theme-engine/hooks/HookRegistry';
import type { HookHandler } from '@salla.sa/twilight-theme-engine/types/hooks';
import { PROMO_SLOTS, type PromoSlot } from './slots';

const promo: HookHandler = () => <p className="promo">Free delivery over 200 SAR</p>;

export function registerPromo(slot: PromoSlot) {
  hookRegistry.register(PROMO_SLOTS[slot], promo);
}

How it behaves

  • At runtime this subpath is the HookName enum alone, in a small shared chunk; the three types are erased. @salla.sa/twilight-theme-engine/hooks, by contrast, loads every engine hook and runs registerDefaultHooks the first time it is imported.

  • It is the same enum object that the package root, /types and /hooks export, so values from any of them compare equal and type-check together.

  • HookDefinition is what hookRegistry.getHandlers(name) returns, highest priority first; id is a registry-wide counter that HookSlot uses as the React key.

  • The handler types, with their traps, are explained on HookHandler, HookHandlers, HookDefinition.

Gotchas

  • HookName is a value, not only a type. import type { HookName } compiles, but HookName.BODY_END then fails with TS1361, "cannot be used as a value because it was imported using 'import type'". Import it without type.

  • A name from this list shows content only where a component renders a HookSlot for it. No engine component renders BODY_INNER, HEAD_INNER, the four SEARCH_* or the three HOMEPAGE_* names, so handlers registered there appear nowhere until your theme adds the slot.

Related

Source and docs