# Theme data (https://docs.salla.dev/twilight/react/data/theme)





Read this when you need the merchant's brand colours, font or theme settings in a component, and you want to know exactly what the object holds.

The **theme object** is what the store's `store/settings` response calls `theme`. The engine loads it once, puts it in the provider at the root of the app, and hands it to your components in two ways.

| You call                         | You get                                              | Use it when                                                                                               |
| -------------------------------- | ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| [`useTheme()`](https://docs.salla.dev/twilight/react/hooks/use-theme) | A small result: `color`, `font`, `settings`, `isRTL` | You need colours, the font or your settings. The common case.                                             |
| `useTwilight().theme`            | The whole theme object                               | You need a field `useTheme` leaves out: `name`, `mode`, `profile`, `assets`, `customization`, `twilight`. |

The text direction of the current *language* is a separate thing: see [`useTranslation`](https://docs.salla.dev/twilight/react/hooks/use-translation).

## Read a setting and a colour [#read-a-setting-and-a-colour]

```tsx title="app/components/common/PromoBar.tsx"
import { useTheme } from '@salla.sa/twilight-theme-engine/hooks/useTheme';

export function PromoBar({ children }: { children: React.ReactNode }) {
  const { color, settings } = useTheme();

  // `!== false`: a store that never saved the setting has no value, and that should mean "on".
  if (settings.header_is_sticky === false) return null;

  return <div style={{ background: color.primary, color: color.reverse_text }}>{children}</div>;
}
```

The same values through the provider:

```tsx
import { useTwilight } from '@salla.sa/twilight-theme-engine/providers';

const { theme } = useTwilight();
theme.mode; // 'live'
theme.settings.header_is_sticky; // true
```

## The full object [#the-full-object]

This is the real `theme` of the public demo store (`1510890315`), trimmed. Search it, or click a key to copy its path.

<JsonExplorer data="themeExample" title="Theme object (demo store 1510890315)" defaultOpen="1" />

## Fields [#fields]

The tables are generated from `Theme` in `@salla.sa/twilight-theme-engine/types`. `color`, `font` and `settings` get their own tables.

{/* types: ../../../../../theme-engine/src/types/index.ts#Theme depth=2 */}

| Field                | Type                                             | Description                                                                                                      |
| -------------------- | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| `id?`                | `number`                                         | Theme id. Not sent by the settings API (absent on the demo store); treat as optional.                            |
| `name`               | `string`                                         | Theme name. The engine adds it to `<body>` as the class `salla-<name>`.                                          |
| `profile?`           | `{ id: number; name: string \| null; }`          | The merchant's theme profile (the saved set of choices).                                                         |
| `mode`               | `string`                                         | 'preview' while the merchant previews a draft (the engine adds the body class `preview-mode`), otherwise 'live'. |
| `is_rtl`             | `boolean`                                        | Whether the theme reads right to left.                                                                           |
| `color`              | `ThemeColor`                                     | Brand colors of the theme.                                                                                       |
| `settings`           | `ThemeSettings`                                  | Merchant values for the theme's settings.                                                                        |
| `assets?`            | `string`                                         | URL template of the theme's published files; `:path` stands for the file path.                                   |
| `bundle_assets?`     | `string`                                         | URL template of component bundles (`:bundle`, `:component`).                                                     |
| `customization?`     | `{ css?: string \| null; js?: string \| null; }` | The merchant's custom CSS and JS, as a URL or inline code. The engine loads them for you.                        |
| `side_menu_enabled?` | `boolean \| null`                                | Whether the merchant turned on the side menu.                                                                    |
| `twilight?`          | `{ version?: string \| null; }`                  | Platform-pinned twilight SDK release, served from the production CDN.                                            |
| `font?`              | `ThemeFont`                                      | The selected font. Can be missing.                                                                               |
| `components?`        | `unknown[]`                                      | Not typed and empty on the demo store. Home blocks do not come from here.                                        |
| `isDark?`            | `boolean \| null`                                | Sent by the platform, usually null. Use `color.is_dark` instead.                                                 |
| `translations_hash?` | `string`                                         | Hash of current translations for cache invalidation                                                              |

#### `profile` [#profile]

| Field  | Type             | Description            |
| ------ | ---------------- | ---------------------- |
| `id`   | `number`         | Profile id.            |
| `name` | `string \| null` | Profile name, or null. |

#### `color` [#color]

| Field             | Type      | Description                                                                             |
| ----------------- | --------- | --------------------------------------------------------------------------------------- |
| `primary`         | `string`  | Primary brand color.                                                                    |
| `text`            | `string`  | Text color chosen for the theme.                                                        |
| `is_dark`         | `boolean` | Dark color scheme. The engine adds `color-mode-dark` or `color-mode-light` to `<body>`. |
| `reverse_primary` | `string`  | The reverse counterpart of the primary color.                                           |
| `reverse_text`    | `string`  | Text color to put on top of `primary`.                                                  |

#### `settings` [#settings]

| Field                             | Type                              | Description                                                                 |
| --------------------------------- | --------------------------------- | --------------------------------------------------------------------------- |
| `font?`                           | `ThemeFont`                       | The selected font.                                                          |
| `imageZoom?`                      | `boolean`                         | Zoom on the product gallery.                                                |
| `show_tags?`                      | `boolean`                         | Show product tags.                                                          |
| `store_color?`                    | `string`                          | Brand color value. Platform-managed.                                        |
| `is_custom_js?`                   | `boolean`                         | Whether the merchant has custom JS. Platform-managed.                       |
| `is_custom_css?`                  | `boolean`                         | Whether the merchant has custom CSS. Platform-managed.                      |
| `homepage_type?`                  | `string`                          | Kind of home page. Platform-managed.                                        |
| `theme_version?`                  | `string`                          | Installed theme version. Platform-managed.                                  |
| `footer_is_dark?`                 | `boolean`                         | Dark footer. Adds `footer-is-dark` or `footer-is-light` to `<body>`.        |
| `topnav_is_dark?`                 | `boolean`                         | Dark top bar. Adds the body class `topnav-is-dark`.                         |
| `use_sar_symbol?`                 | `boolean`                         | Show the Saudi riyal symbol instead of the currency code.                   |
| `important_links?`                | `boolean`                         | Show the important-links block. Platform-managed.                           |
| `store_font_type?`                | `string`                          | Font type of the store. Platform-managed.                                   |
| `footer_menu_type?`               | `string`                          | Footer menu variant. Platform-managed.                                      |
| `header_is_sticky?`               | `boolean`                         | Keep the main menu at the top while scrolling.                              |
| `product_show_breadcrumbs?`       | `boolean`                         | Breadcrumb trail on the product page (default on).                          |
| `product_index_show_breadcrumbs?` | `boolean`                         | Breadcrumb trail on product list pages (default on).                        |
| `notify_when_available_in_card?`  | `boolean`                         | Out-of-stock cards offer "notify me when available" (default on).           |
| `header_menu_type?`               | `string`                          | Header menu variant. Platform-managed.                                      |
| `header_layout?`                  | `"default" \| "lite"`             | Header layout variant of the reference theme.                               |
| `footer_layout?`                  | `"centered" \| "columns"`         | Footer layout variant of the reference theme.                               |
| `product_card_img_ratio?`         | `string \| { value?: string; }[]` | Product card image ratio. Either shape can arrive.                          |
| `default_font_name?`              | `string`                          | Name of the default font. Platform-managed.                                 |
| `sticky_add_to_cart?`             | `boolean`                         | Sticky add-to-cart bar on mobile. Adds `is-sticky-product-bar` to `<body>`. |
| `customization_js_ver?`           | `number \| null`                  | Version of the merchant's custom JS, or null. Platform-managed.             |
| `customization_css_ver?`          | `number \| null`                  | Version of the merchant's custom CSS, or null. Platform-managed.            |
| `translations_hash?`              | `string`                          | Hash of current translations (also sent at `theme.translations_hash`).      |
| `is_more_button_enabled?`         | `boolean`                         | The "All" button on home blocks.                                            |
| `slider_background_size?`         | `"contain" \| "cover"`            | How product gallery images fit their frame.                                 |
| `vertical_fixed_products?`        | `boolean`                         | Show products in a vertical fixed layout.                                   |
| `is_custom_widgets_enabled?`      | `boolean`                         | Custom widgets are enabled.                                                 |
| `squar_photo_bg_image_size?`      | `"contain" \| "cover"`            | How images fit in the square-photos block.                                  |
| `is_show_more_detail_enabled?`    | `boolean`                         | Show the "more details" control.                                            |
| `is_breadcrumbs_enabled?`         | `boolean`                         | Breadcrumbs on or off.                                                      |
| `placeholder?`                    | `string`                          | Image the SDK's product cards show when a product has none.                 |
| `enable_add_product_toast?`       | `boolean`                         | Show a toast after adding to the cart.                                      |
| `enable_more_menu?`               | `boolean`                         | Show the "More" menu.                                                       |

#### `settings.font` [#settingsfont]

| Field          | Type               | Description                                                                      |
| -------------- | ------------------ | -------------------------------------------------------------------------------- |
| `id?`          | `number`           | Font id.                                                                         |
| `name`         | `string`           | Font family name.                                                                |
| `path?`        | `string`           | Relative path of the stylesheet that loads the font.                             |
| `url?`         | `string`           | Stylesheet URL that loads the font.                                              |
| `type?`        | `string \| number` | Source of the font. `theme.font` sends a string, `theme.settings.font` a number. |
| `family_name?` | `string`           | CSS family name. Present on `settings.font`, not on `theme.font`.                |

#### `customization` [#customization]

| Field  | Type             | Description          |
| ------ | ---------------- | -------------------- |
| `css?` | `string \| null` | Custom CSS, or null. |
| `js?`  | `string \| null` | Custom JS, or null.  |

#### `twilight` [#twilight]

| Field      | Type             | Description                      |
| ---------- | ---------------- | -------------------------------- |
| `version?` | `string \| null` | The pinned SDK version, or null. |

#### `font` [#font]

Same fields as `settings.font`.

{/* /types */}

`settings` holds every merchant-editable value, flat, keyed by the `id` you declared in `twilight.json`. The engine types only the keys the reference theme uses. A store's `settings` can hold more keys than the type lists, so read only the keys you declared.

Settings the engine reads itself (`footer_is_dark`, `footer_layout`, `topnav_is_dark`, `sticky_add_to_cart`, `slider_background_size`, `header_is_sticky`) work even when your theme never reads them.

In the theme editor's preview, `header_is_sticky` reads `false` whatever the merchant chose: a pinned header would cover the action bar of the blocks scrolled under it. A theme that pins its header from this setting needs no change; one that pins it unconditionally stays pinned in the preview.

## Features and home blocks [#features-and-home-blocks]

* **`features`** (such as `"mega-menu"`, `"fonts"`) are declared in `twilight.json` for the dashboard. They are not part of the runtime theme object: you cannot read them from `useTheme`.
* **Home blocks** are loaded by the [home route](https://docs.salla.dev/twilight/react/routes/home), not read from the theme. A block's values reach your component as a `data` prop. See [Add a home block](https://docs.salla.dev/twilight/react/recipes/add-a-home-block).

## How CSS gets its values [#how-css-gets-its-values]

When the page mounts in the browser, the engine copies the theme onto the root element as CSS variables, so styles need no JavaScript:

| Variable                                                                  | Value                                  |
| ------------------------------------------------------------------------- | -------------------------------------- |
| `--color-primary`                                                         | `color.primary`                        |
| `--color-primary-dark`, `--color-primary-light`                           | `primary` darkened or lightened by 15% |
| `--color-title`, `--color-secondary`                                      | `color.primary`                        |
| `--color-primary-reverse`, `--color-text-reverse`, `--color-reverse-text` | `color.reverse_text`                   |
| `--color-reverse-primary`                                                 | `color.reverse_primary`                |
| `--color-text`                                                            | Always `#222222`, not `color.text`     |
| `--font-main`, `--font-light`, `--font-regular`                           | `font.name`                            |
| `--font-medium`, `--font-bold`                                            | `font.name` plus `-Medium` or `-Bold`  |

See [Styling](https://docs.salla.dev/twilight/react/guide/styling).

## From twilight.json to a value [#from-twilightjson-to-a-value]

You declare a setting once in `twilight.json` ([Settings guide](https://docs.salla.dev/twilight/react/guide/settings)). The merchant picks a value in the dashboard, and the key appears in `theme.settings` under the same `id`.

```json title="twilight.json"
{ "id": "header_is_sticky", "type": "boolean", "format": "switch", "value": true }
```

```ts
settings.header_is_sticky; // true  (a plain boolean)
```

```json title="twilight.json"
{
  "id": "slider_background_size",
  "type": "items",
  "format": "dropdown-list",
  "options": [{ "label": "Cover", "value": "cover" }, { "label": "Contain", "value": "contain" }],
  "selected": [{ "label": "Contain", "value": "contain" }]
}
```

```ts
settings.slider_background_size; // "cover"  (the live store sends the chosen option's value)
```

In `twilight.json` the default sits in `selected` as an option object, but the live store sends the chosen `value` as a string. `product_card_img_ratio` is typed to accept `[{ value }]` as well: see the gotchas.

```json title="twilight.json"
{ "id": "title", "type": "string", "format": "text", "multilanguage": true }
```

Text, textarea and image fields are used by [home block](https://docs.salla.dev/twilight/react/recipes/add-a-home-block) fields: the value reaches your block as `data.title`. The demo store has no plain-text theme setting to show a real runtime value.

```json title="twilight.json"
{ "type": "string", "id": "background", "format": "image" }
```

In a home block, `background` is a string on `data`. Type it as `string | undefined` and guard it.

`static` entries (titles, lines, descriptions) only decorate the dashboard and have no runtime value. Entries typed `collection` and `variable-list` belong to home block fields.

## Common tasks [#common-tasks]

A boolean that defaults to on:

```tsx
const sticky = useTheme().settings.header_is_sticky !== false;
```

A dropdown value, from a string or `[{ value }]`:

```tsx
function dropdownValue(raw: unknown): string | undefined {
  const first = Array.isArray(raw) ? raw[0] : raw;
  return typeof first === 'string' ? first : (first as { value?: string } | undefined)?.value;
}
const fit = dropdownValue(settings.slider_background_size) ?? 'cover';
```

A colour in an inline style, with readable text on top:

```tsx
const { color } = useTheme();
<button style={{ background: color.primary, color: color.reverse_text }}>Buy</button>;
```

The font name, safely:

```tsx
const { font } = useTheme();
const family = font?.name ?? 'inherit';
```

Direction:

```tsx
const { isRTL } = useTheme();
<div dir={isRTL ? 'rtl' : 'ltr'} />;
```

## Gotchas [#gotchas]

* **Value shapes differ per widget.** A switch is a boolean, a dropdown is the chosen `value`. Check the shape before using it.
* **A dropdown can be a string or `[{ value }]`.** `product_card_img_ratio` is typed to allow both. Normalise with a helper like the one above.
* **Settings can be `undefined`.** Until the merchant saves, a key may be missing. Test `!== false` for "on by default".
* **`font` is optional**, and `settings.font` is a different object (with `family_name`). `useTheme().font` is the `font` field.
* **CSS variables are set in the browser.** The engine writes them when the page mounts, so on the server render they are not there yet. The theme object itself is available on the server and the client.
* **`--color-text` is `#222222`**, not `color.text`. Read `color.text` from the hook when you need it.
* **`isRTL` is the theme's direction.** Use [`useTranslation`](https://docs.salla.dev/twilight/react/hooks/use-translation) for the direction of the current language.

## Next [#next]

* [Settings guide](https://docs.salla.dev/twilight/react/guide/settings): declare settings in `twilight.json`.
* [`useTheme`](https://docs.salla.dev/twilight/react/hooks/use-theme): the hook's API.
* [Store data](https://docs.salla.dev/twilight/react/data/store): the store object next to the theme.
* [Styling](https://docs.salla.dev/twilight/react/guide/styling): use the colours and fonts in CSS.
