Theme data

Every field of the theme object that useTheme and useTwilight().theme return, with real values from a live store.

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 callYou getUse it when
useTheme()A small result: color, font, settings, isRTLYou need colours, the font or your settings. The common case.
useTwilight().themeThe whole theme objectYou 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.

Read a setting and a colour

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:

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

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

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.

Theme object (demo store 1510890315)
{ 15 }
:"1298199463"
:{ 2 }
:"live"
:false
:"178990889138"
:{ 5 }
:{ 5 }
:{ 15 }
:"https://cdn.assets.salla.network/themes/1247874246/1.377.0/:path"
:"https://cdn.assets.salla.network/themes/:bundle/latest/:component.js"
:{ 1 }
:{ 2 }
:null
:[ 0 ]
:null
Click a key to copy its path.

Fields

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

FieldTypeDescription
id?numberTheme id. Not sent by the settings API (absent on the demo store); treat as optional.
namestringTheme 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).
modestring'preview' while the merchant previews a draft (the engine adds the body class preview-mode), otherwise 'live'.
is_rtlbooleanWhether the theme reads right to left.
colorThemeColorBrand colors of the theme.
settingsThemeSettingsMerchant values for the theme's settings.
assets?stringURL template of the theme's published files; :path stands for the file path.
bundle_assets?stringURL 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 | nullWhether the merchant turned on the side menu.
twilight?{ version?: string | null; }Platform-pinned twilight SDK release, served from the production CDN.
font?ThemeFontThe selected font. Can be missing.
components?unknown[]Not typed and empty on the demo store. Home blocks do not come from here.
isDark?boolean | nullSent by the platform, usually null. Use color.is_dark instead.
translations_hash?stringHash of current translations for cache invalidation

profile

FieldTypeDescription
idnumberProfile id.
namestring | nullProfile name, or null.

color

FieldTypeDescription
primarystringPrimary brand color.
textstringText color chosen for the theme.
is_darkbooleanDark color scheme. The engine adds color-mode-dark or color-mode-light to <body>.
reverse_primarystringThe reverse counterpart of the primary color.
reverse_textstringText color to put on top of primary.

settings

FieldTypeDescription
font?ThemeFontThe selected font.
imageZoom?booleanZoom on the product gallery.
show_tags?booleanShow product tags.
store_color?stringBrand color value. Platform-managed.
is_custom_js?booleanWhether the merchant has custom JS. Platform-managed.
is_custom_css?booleanWhether the merchant has custom CSS. Platform-managed.
homepage_type?stringKind of home page. Platform-managed.
theme_version?stringInstalled theme version. Platform-managed.
footer_is_dark?booleanDark footer. Adds footer-is-dark or footer-is-light to <body>.
topnav_is_dark?booleanDark top bar. Adds the body class topnav-is-dark.
use_sar_symbol?booleanShow the Saudi riyal symbol instead of the currency code.
important_links?booleanShow the important-links block. Platform-managed.
store_font_type?stringFont type of the store. Platform-managed.
footer_menu_type?stringFooter menu variant. Platform-managed.
header_is_sticky?booleanKeep the main menu at the top while scrolling.
product_show_breadcrumbs?booleanBreadcrumb trail on the product page (default on).
product_index_show_breadcrumbs?booleanBreadcrumb trail on product list pages (default on).
notify_when_available_in_card?booleanOut-of-stock cards offer "notify me when available" (default on).
header_menu_type?stringHeader 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?stringName of the default font. Platform-managed.
sticky_add_to_cart?booleanSticky add-to-cart bar on mobile. Adds is-sticky-product-bar to <body>.
customization_js_ver?number | nullVersion of the merchant's custom JS, or null. Platform-managed.
customization_css_ver?number | nullVersion of the merchant's custom CSS, or null. Platform-managed.
translations_hash?stringHash of current translations (also sent at theme.translations_hash).
is_more_button_enabled?booleanThe "All" button on home blocks.
slider_background_size?"contain" | "cover"How product gallery images fit their frame.
vertical_fixed_products?booleanShow products in a vertical fixed layout.
is_custom_widgets_enabled?booleanCustom widgets are enabled.
squar_photo_bg_image_size?"contain" | "cover"How images fit in the square-photos block.
is_show_more_detail_enabled?booleanShow the "more details" control.
is_breadcrumbs_enabled?booleanBreadcrumbs on or off.
placeholder?stringImage the SDK's product cards show when a product has none.
enable_add_product_toast?booleanShow a toast after adding to the cart.
enable_more_menu?booleanShow the "More" menu.

settings.font

FieldTypeDescription
id?numberFont id.
namestringFont family name.
path?stringRelative path of the stylesheet that loads the font.
url?stringStylesheet URL that loads the font.
type?string | numberSource of the font. theme.font sends a string, theme.settings.font a number.
family_name?stringCSS family name. Present on settings.font, not on theme.font.

customization

FieldTypeDescription
css?string | nullCustom CSS, or null.
js?string | nullCustom JS, or null.

twilight

FieldTypeDescription
version?string | nullThe pinned SDK version, or null.

font

Same fields as settings.font.

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.

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, not read from the theme. A block's values reach your component as a data prop. See Add a home block.

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:

VariableValue
--color-primarycolor.primary
--color-primary-dark, --color-primary-lightprimary darkened or lightened by 15%
--color-title, --color-secondarycolor.primary
--color-primary-reverse, --color-text-reverse, --color-reverse-textcolor.reverse_text
--color-reverse-primarycolor.reverse_primary
--color-textAlways #222222, not color.text
--font-main, --font-light, --font-regularfont.name
--font-medium, --font-boldfont.name plus -Medium or -Bold

See Styling.

From twilight.json to a value

You declare a setting once in twilight.json (Settings guide). The merchant picks a value in the dashboard, and the key appears in theme.settings under the same id.

twilight.json
{ "id": "header_is_sticky", "type": "boolean", "format": "switch", "value": true }
settings.header_is_sticky; // true  (a plain boolean)

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

A boolean that defaults to on:

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

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

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:

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

The font name, safely:

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

Direction:

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

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 for the direction of the current language.

Next

On this page