Store data

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.

Where you read it

There are two ways to get the same store object.

You writeYou get
useStore()The store fields plus a refresh() method.
useTwilight().storeThe store fields only.

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.

app/components/layout/StoreBadge.tsx
import { useStore } from '@salla.sa/twilight-theme-engine/hooks/useStore';

export function StoreBadge() {
  const { name, logo, url, contacts, settings } = useStore();

  return (
    <a href={url}>
      <img src={logo} alt={name} />
      {contacts.email && <span>{contacts.email}</span>}
      {settings.rating_enabled && <span>Rated by customers</span>}
    </a>
  );
}

The full object

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://cdn.salla.network/salla.com/logo-wide-1.svg"
:"https://cdn.salla.network/salla.com/logo-wide-1.svg"
:"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.

Fields

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.

FieldTypeDescription
idnumberStore id.
namestringStore name, as the merchant typed it.
usernamestringStore username.
descriptionstringStore description, as HTML rather than plain text.
slogan?stringStore slogan.
logostringLogo image URL.
urlstringStore home URL. On a multilingual store it ends with the language prefix (/ar/).
api?stringBase URL of the store API.
iconstringIcon image URL.
favicon?stringFavicon URL. Marked for removal.
about?stringLonger "about the store" text.
created_at?stringWhen the store was created.
updated_at?stringWhen the store was last updated.
meta?{ title?: string; description?: string; keywords?: string; }Default SEO values for pages that set none. Empty strings when the merchant set none.
settingsStoreSettingsStore-level settings (auth, cart, product, ratings and so on).
contactsStoreContactsContact details the store shows to customers.
socialStoreSocialLinks to the store's social media profiles.
countrystringStore's default country code (uppercase ISO, e.g., "SA").
store_country?stringCountry the store operates in (uppercase ISO, e.g., "SA").
ray?numberInternal platform request value; nothing in a theme should depend on it.
features?string[]Platform feature flags that are on for this store.
apps?StoreAppsMobile app download links.
template?string | nullReserved by the platform; usually null.
scope?StoreScope | nullThe selected market or branch, or null when the store has none.
is_merchant?booleanWhether the visitor is the merchant. Marked for removal: rely on theme.mode instead.
support_pickup?booleanWhether the store offers pickup (mirrors shipping.support_pickup).
shipping?StoreShippingShipping and delivery options the store offers.
rating?{ total: number; stars: number; }Store-wide rating summary.
ratings?{ stars: number; total: number; }[]Rating distribution: how many ratings gave each star value.
order_instruction?StoreOrderInstructionOrder confirmation page messages (HTML strings).

meta

FieldTypeDescription
title?stringDefault page title.
description?stringDefault page description.
keywords?stringDefault page keywords.

settings

FieldTypeDescription
auth{ email_allowed: boolean; mobile_allowed: boolean; is_email_required: boolean; countrie...Sign-in and registration options.
cart{ apply_coupon_enabled: boolean; basket_gap?: boolean; multi_coupon?: boolean; }Cart options.
product{ total_sold_enabled: number; manual_quantity?: boolean; fit_type?: 'cover' | 'contain'...Product page and listing options.
category{ testimonial_enabled: boolean; }Category page options.
payments?string[]Enabled payment methods.
arabic_numbers_enabledbooleanShow Arabic-Indic digits.
content_copyright?booleanContent copy protection is on.
use_sar_symbol?booleanShow the Saudi riyal symbol instead of the currency code.
is_multilingualbooleanThe store offers more than one language.
currencies_enabledbooleanThe store offers more than one currency.
rating_enabledbooleanRatings are turned on for the store.
rating?{ is_enabled: boolean; show_on_category: boolean; show_on_product: boolean; can_rate_st...Rating and review options.
blog?{ is_enabled: boolean; allow_likes_and_comments: boolean; }Blog options.
is_loyalty_enabled?booleanThe loyalty program is on.
keys?{ maps?: string; gtm?: string[]; sift?: string; }Public keys for third-party services.
is_salla_gateway?booleanThe store uses the Salla payment gateway.
upload_size?numberMaximum upload size.
tax?{ number?: string; certificate?: string | null; taxable_prices_enabled: boolean; }Tax details.
certificate?{ id: string; } | nullCommerce certificate details, or null.
made_in_ksa?booleanShow the "Made in KSA" mark.
commercial_number?string | nullCommercial registration number, or null.
freelance_number?string | nullFreelance license number, or null.
buy_now?string | BuyNowSettings | nullFast-checkout (Apple Pay style) configuration object, or null when off. Typed string | null in older releases; the API sends an object.
installments?string | unknown[] | Record<string, unknown> | nullInstallment providers. An empty array means none, and an empty array is truthy.
quick_order?string | Record<string, unknown> | nullQuick-order configuration, or null when off.
bullet_delivery?string | Record<string, unknown> | nullFast ("bullet") delivery configuration, or null when off.
ticketing_system_enabled?booleanSupport tickets are on.
opening_hours?OpeningHoursSettingsOpening hours for receiving orders. Not yet sent by the API.
features?{ price_quote?: boolean; 'pre-order-campaigns'?: boolean; }Feature flags. Not yet sent by the API.

settings.auth

FieldTypeDescription
email_allowedbooleanCustomers can sign in with email.
mobile_allowedbooleanCustomers can sign in with a mobile number.
is_email_requiredbooleanEmail is required when registering.
countries?string[]Country codes allowed for mobile numbers, lowercase.
force_login?booleanVisitors must sign in to browse the store.
whatsapp_allowed?booleanCustomers can sign in through WhatsApp.
whatsapp_countries?string[]Country codes where WhatsApp sign-in is offered.
whatsapp_merchant_allowed?booleanWhether the merchant has enabled WhatsApp sign-in.
user_country?stringVisitor's detected country (uppercase ISO), e.g. "DE".
config?unknownExtra sign-in configuration sent by the platform; its shape is not typed, and it is null when unused.

settings.cart

FieldTypeDescription
apply_coupon_enabledbooleanShow the coupon field in the cart.
basket_gap?booleanPlatform flag for the cart layout.
multi_coupon?booleanMore than one coupon can be applied.

settings.product

FieldTypeDescription
total_sold_enablednumberShow how many units were sold. It is 1 or 0, not a boolean.
manual_quantity?booleanCustomers can type the quantity instead of using a stepper.
fit_type?"contain" | "cover" | nullHow product images fill their frame; null when not set.
related_products_enabled?booleanShow related products.
filters?boolean | ProductFiltersSettings | nullSwitches for the listing filters, one per filter ({ category_id: true, price: true, ... }).
product-recommendation-type?stringKind of product recommendations to show. The key has hyphens, so read it with brackets.
bought_together?booleanShow "bought together" products.
show_comments?booleanShow product comments.
user_can_comment?booleanCustomers can comment on products.
show_price_as_dash?booleanHide prices and show a dash instead.
notify_options_availability?booleanOffer "notify me" for sold-out options.
show_special_offers?booleanShow special offers on the product.
show_more?booleanShow the "show more" control.
availability_notify?{ email: boolean; sms: boolean; mobile: boolean; whatsapp: boolean; } | nullChannels offered for "notify me when available", or null when the feature is off.

settings.product.availability_notify

FieldTypeDescription
emailbooleanNotify by email.
smsbooleanNotify by SMS.
mobilebooleanNotify by mobile notification.
whatsappbooleanNotify by WhatsApp.

settings.category

FieldTypeDescription
testimonial_enabledbooleanShow testimonials on category pages.

settings.rating

FieldTypeDescription
is_enabledbooleanRatings are on.
show_on_categorybooleanShow ratings on category pages.
show_on_productbooleanShow ratings on product pages.
can_rate_storebooleanCustomers can rate the store.
can_rate_productbooleanCustomers can rate products.
can_rate_shippingbooleanCustomers can rate shipping.
show_rating_summarybooleanShow the rating summary block.
show_recommendationbooleanShow the "would you recommend" question.
allow_likesbooleanReviews can be liked.
allow_attach_imagesbooleanReviews can include images.
allow_contact_supportbooleanShow a contact-support action on reviews.
allow_updatebooleanCustomers can edit their review.
update_periodnumberNumber of days a review can be edited.
can_customer_hide_namebooleanReviewers can hide their name.
visitor_can_commentbooleanVisitors who are not signed in can comment.
page_feedback_enabledbooleanPage feedback is on.

settings.blog

FieldTypeDescription
is_enabledbooleanThe blog is on.
allow_likes_and_commentsbooleanReaders can like and comment on articles.

settings.keys

FieldTypeDescription
maps?stringMaps API key for the storefront.
gtm?string[]Google Tag Manager container ids.
sift?stringSift Science beacon key for fraud detection. Not yet sent by the API.

settings.tax

FieldTypeDescription
number?stringTax registration number.
certificate?string | nullTax certificate image URL, or null.
taxable_prices_enabledbooleanPrices include tax.

settings.certificate

FieldTypeDescription
idstringCommerce certificate id.

settings.opening_hours

FieldTypeDescription
enabled?booleanThe store only takes orders during opening hours.
hours?Record<string, string[]>Time ranges per lowercase day name (monday, tuesday, ...). A day with no entry or an empty list is closed.

settings.features

FieldTypeDescription
price_quote?booleanCustomers can ask for a price quote.
pre-order-campaigns?booleanPre-order campaigns are available.

contacts

FieldTypeDescription
mobile?stringMobile number.
phone?stringPhone number.
email?stringSupport email address.
whatsapp?stringWhatsApp link or number.
telegram?stringTelegram link.

social

FieldTypeDescription
instagram?stringInstagram profile link.
snapchat?stringSnapchat profile link.
twitter?stringX (Twitter) profile link.
youtube?stringYouTube channel link.
facebook?stringFacebook page link.
pinterest?stringPinterest profile link.
maroof?stringMaroof page link.
whatsapp?stringWhatsApp link.
tiktok?stringTikTok profile link.

apps

FieldTypeDescription
appstore?stringApp Store link.
googleplay?stringGoogle Play link.

scope

FieldTypeDescription
id?numberScope id.
namestringMarket or branch name.
selected?booleanThis scope is the active one.
type?stringScope type, such as a branch.
is_open?booleanThe scope is open.
display_as"default" | "inline" | "popup"How the scope selector is shown.
languages?string[]Available language codes (lowercase, e.g., ["ar", "en"])
currencies?string[]Available currency codes (e.g., ["SAR", "USD"])
countries?string[]Available country codes (uppercase ISO, e.g., ["SA", "AE"])
always_ask?booleanAsk the visitor to choose a scope.
allocation?unknownAllocation details sent by the platform, or null; its shape is not typed.

shipping

FieldTypeDescription
delivery_location?unknownDelivery location details, or null when the store has none.
express_delivery_promise?unknownExpress-delivery promise details, or null when the store has none.
support_pickup?booleanWhether the store offers pickup.
has_bullet_delivery_tag?booleanWhether products show the fast-delivery ("bullet") tag.

rating

FieldTypeDescription
totalnumberNumber of ratings the store has received.
starsnumberAverage star rating.

ratings

FieldTypeDescription
starsnumberThe star value (for example 5).
totalnumberNumber of ratings that gave this star value.

order_instruction

FieldTypeDescription
thank_title?stringHeading of the order confirmation page.
order_instructions_payment_waiting?stringMessage shown while the order waits for payment.
order_instructions_under_review?stringMessage shown while the order is under review.
order_instructions_completed?stringMessage shown once the order is completed.

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.

refresh

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.

Common tasks

Is the store multilingual, and which languages?

is_multilingual is on the store. The list of languages is on settings, as an array.

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

function Languages() {
  const { store, settings, locale } = useTwilight();
  if (!store.settings?.is_multilingual) return null;

  return (
    <ul>
      {settings.languages?.map((lang) => (
        <li key={lang.code} aria-current={lang.code === locale}>
          {lang.name} {lang.is_rtl ? '(RTL)' : ''}
        </li>
      ))}
    </ul>
  );
}

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.

Which currencies are available?

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.

const { store, settings } = useTwilight();
const codes = store.settings?.currencies_enabled ? Object.keys(settings.currencies ?? {}) : [];
// ["AED", "AUD", "BHD", …, "SAR", "USD"]

Do customers sign in by email or mobile?

const { auth } = useStore().settings;
const methods = [auth.email_allowed && 'email', auth.mobile_allowed && 'mobile'].filter(Boolean);
// demo store: ["email"]

When force_login is true, send visitors to sign in before they browse.

Is the store open right now?

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>;
}

Which payment methods and features are on?

const { settings, features = [] } = useStore();
const acceptsCash = settings.payments?.includes('cod');
const guestCheckout = features.includes('guest-checkout');

Free shipping and cart settings

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.

Gotchas

  • 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.

Next

On this page