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

useTwilight

hookBeginnerserverbrowserlive demo

Reads everything TwilightProvider knows: store, theme, settings, language, direction, current page, login token and the Salla SDK.

import { useTwilight, TwilightContextValue } from '@salla.sa/twilight-theme-engine';

In plain words

A hook is a function whose name starts with use, called at the top of a component to get something. useTwilight() hands your component what TwilightProvider knows about the page being shown: the store, the merchant's theme, the language and text direction, the current address, whether a customer is signed in, and the Salla SDK (window.Salla) once the browser has loaded it.

The focused hooks (useStore, useTheme, useTranslation) read better when you need one thing. Reach for useTwilight() when you need several.

Signature

function useTwilight(): TwilightContextValue   // throws outside TwilightProvider

interface TwilightContextValue {
  isReady: boolean;
  store: Store;
  theme: Theme;
  settings: StoreContext;          // the whole store settings response
  locale: string;                  // 'ar'
  dir: 'ltr' | 'rtl';
  routeId: string;
  location: TwilightLocation;
  authToken: string | null;
  salla: SallaSDK | undefined;     // undefined in the server render
  i18n: i18n;                      // the i18next instance
  config: TwilightConfig;          // { debug }
  log: TwilightLog;                // styled console helpers
  currency: SallaCurrency | null;  // always null today
  extras?: Record<string, unknown>;
}

Try it live

The context value this page was rendered with. Pick a field to look inside; everything is the demo store’s real data.Try this: pick settings: it is the whole store settings response, which store and theme come from.
Storefront canvas · ar · RTL
Open the browser console to see the styled log line.
useTwilight() → store: {…} 24 keys
id: 1510890315
ray: 50
logo: "https://cdn.salla.network/salla.com/logo-wide-1.svg"
icon: "https://cdn.salla.network/salla.com/logo-wide-1.svg"
name: "ثيم رائد"
username: "dev-vgckq3fssfhjewwi"
store_country: "SA"
country: "SA"
url: "https://demostore.salla.sa/ar/dev-vgckq3fssfhjewwi/"
settings: {…} 26 keys
meta: {…} 3 keys
scope: null
template: null
contacts: {…} 4 keys
social: {…} 4 keys
description: "<p class="ql-direction-rtl">هذا المتجر التجريبي يتيح لك استكشاف شكل وتصميم المتاجر على منصة <strong>سلة</strong>. تصفّح الأقسام، جرّب تجربة الشراء، واستعرض الم…"
apps: {…} 2 keys
features: Array(18)
is_merchant: false
support_pickup: true
order_instruction: {…} 4 keys
shipping: {…} 3 keys
rating: {…} 2 keys
ratings: Array(2)
Controls
What a theme writes
import { useTwilight } from '@salla.sa/twilight-theme-engine';

export function Example() {
  const { store } = useTwilight();
  return <span>{store.name}</span>;
}

Example

app/components/StoreHeading.tsx
import { useTwilight } from '@salla.sa/twilight-theme-engine';

export function StoreHeading() {
  const { store, theme, locale, dir } = useTwilight();
  return (
    <h1 lang={locale} dir={dir} style={{ color: theme.color.primary }}>
      {store.name}
    </h1>
  );
}

How it behaves

  • store, theme, isReady and authToken are React state: when they change, every component using the hook renders again. settings, locale, dir, routeId, location, i18n and extras are getters that read the request context when you access them, so they are current when read but never cause a render themselves. useRouteId() and the useIs* hooks subscribe for you.

  • store and theme hold the values the page was first rendered with. useStore().refresh() updates store; in development the dev settings widget overlays theme.settings.

  • salla reads window.Salla on each access: undefined in the server render and until the SDK script has run.

  • log prints styled console output (info, warn, error, label, dir, trace, group, groupCollapsed, groupEnd) whatever debug is set to.

  • Hook slot handlers receive this same value as context.twilight. The hook is also exported from /providers.

Gotchas

  • authToken is null in every server render, even for a signed-in customer: the provider seeds that state from the context or localStorage only in the browser (src/providers/TwilightProvider.tsx). Markup that depends on it differs between server and browser, a hydration mismatch. Decide after hydration, for example with useIsClient() from @salla.sa/twilight-theme-engine/hooks.

  • currency is always null: it is created with useState(null) and never set (src/providers/twilight-init.ts). Format prices with useMoney().

  • Reading settings throws SettingsError when the request context holds no settings (the getter in src/twilight/context.ts). Inside a rendered page they are always present.

Related

Source and docs