Every field of the store object returned by useStore and useTwilight().store, with real example values from a demo store.
Read this page when you need to know what the store object looks like: which fields exist, which can be missing, and where to find things like languages and currencies.
The engine loads the store once per request from the store/settings API and hands it to the provider at the root of your app. It is available in server rendering and in the browser, from the first render.
Languages and currencies are not inside the store object. They come from the same API response and you read them from useTwilight().settings (see Common tasks). The theme object is covered in Theme data.
This is the store of the public demo store 1510890315, shortened: long arrays are cut to a few items and long strings are trimmed. Search it, expand what you need, and click a key to copy its path. Notes sit next to the less obvious fields.
Store object (demo store 1510890315)
{ 24 }
:1510890315number
:50internal platform value, ignore it
:"ثيم رائد"entered by the merchant, so not translated
:"dev-vgckq3fssfhjewwi"
:"<p>This demo store allows you to explore…</p>"HTML string
:"https://raed.salla.design/en/"includes the current language prefix
:"SA"
:"SA"
:false
:true
:{ 26 }
:{ 3 }
:{ 4 }
:{ 4 }
:{ 2 }
:[ 4 ]
:nullset only when the store uses markets or branches
:null
:{ 4 }
:{ 2 }
:{ 2 }
:[ 2 ]
Click a key to copy its path.
Typed and untyped fields
The Store type describes the fields themes read. The API can return more (for example extra settings.rating options). TypeScript does not know about those, so read them with a cast or your own type.
The tables below are generated from the engine's Store type. Nested objects get their own table, named by their path (settings.auth, settings.cart, and so on). Example values are in the explorer above.
Field
Type
Description
id
number
Store id.
name
string
Store name, as the merchant typed it.
username
string
Store username.
description
string
Store description, as HTML rather than plain text.
slogan?
string
Store slogan.
logo
string
Logo image URL.
url
string
Store home URL. On a multilingual store it ends with the language prefix (/ar/).
The API still sends more than the type lists: for example settings.rating also carries video and points options (allow_attach_videos, required_attach_images, rating_store_points). buy_now, installments, quick_order and bullet_delivery can be an object, an array or null, so check before you use them (in the demo, buy_now is an object and installments is []).
settings.features is not the top-level features array of strings. settings.opening_hours is read by useOpeningHours. scope is null unless the store uses markets or branches; the demo store has none, so there is no real example in the explorer.
Only on useStore(). refresh(): Promise<void> re-reads store from the Salla SDK config and merges it, one level deep, over the current store. It does nothing when the SDK is not loaded yet, and ignores errors.
Demo values: { "name": "العربية", "code": "ar", "is_rtl": true, "country_code": "sa", "url": "https://assets.salla.sa/images/flags/ar.svg" }. The url is the flag icon, not a page. The engine also adds iso_code, equal to code. See Languages and RTL.
settings.currencies is an object keyed by currency code. amount is the exchange rate against the store currency (in the demo, USD.amount is 0.267589 and SAR.amount is 1). To format prices, use useMoney.
opening_hours is passed to useOpeningHours, which returns isOpen, isEnabled, nextOpen and nextOpenFormatted. It treats the store as open when opening hours are not enabled.
import { useStore } from '@salla.sa/twilight-theme-engine/hooks/useStore';import { useOpeningHours } from '@salla.sa/twilight-theme-engine/hooks';function ClosedNotice() { const { settings } = useStore(); const { isOpen, nextOpenFormatted } = useOpeningHours(settings.opening_hours); return isOpen ? null : <p>We are closed. We open {nextOpenFormatted}.</p>;}
Free shipping progress is part of the cart, not the store. See Cart data. Store-level cart switches are in settings.cart, for example settings.cart.apply_coupon_enabled.
Many fields are optional.slogan, about, favicon, api, scope, opening_hours, social.* and contacts.* can be missing. Use optional chaining and test for presence before you render a link.
Types are looser than the data. Several settings (filters, buy_now, installments) are unions of a boolean or string, an object and null, so narrow them before use. Some real fields are not typed at all.
store.id is a number, but ids on other objects, such as certificate.id, are strings. Compare with the right type, or convert before you compare.
Some setting keys are not valid identifiers.settings.product['product-recommendation-type'] and settings.features['pre-order-campaigns'] need bracket access.
Flags that are numbers.settings.product.total_sold_enabled is 1 or 0.
Language-dependent values. The API response follows the page language, so url carries the language prefix (/en/). name and description are what the merchant typed and are not translated.
description is HTML. Sanitise it or render it with care.
Empty store object. If the provider is created without settings, store is {} until settings arrive, so store.settings is undefined. Use store.settings?.… in code that can run that early.
Server and browser see the same store. It comes from the settings loaded for the request, so server and first browser render match. refresh() only exists in the browser, because it needs the Salla SDK.
useStore() returns a new object on every render. Use useTwilight().store, which keeps its identity until refresh(), or depend on the fields you read, in effect and memo dependencies.
settings on useTwilight() is not store.settings.useTwilight().settings is the whole settings response (store, theme, languages, currencies, and more). store.settings is only the store-level settings group.