Theme globals
Every window.theme key, what writes it, and what reads it.
Theme globals
Liquid hands data to JavaScript through window.theme. Every key is declared in the theme interface in
src/@types/global.ts, which is the authoritative list.
A key is only present on pages where the Liquid that writes it rendered. Treat every read as possibly undefined.
const config = window.theme?.medispaCalendarConfig;
if (!config) return;Regenerate this page
sed -n '/^ theme: {/,/^ };/p' src/@types/global.tsFeature configuration
| Key | Written by | Read by |
|---|---|---|
medispaCalendarConfig | snippets/medispa-calendar-config.liquid | The React booking calendar |
cartRewardBanner | layout/theme.liquid | src/entrypoints/cart-reward-banner.ts, src/entrypoints/homepage-prominence-banner.ts |
popupManagerConfig | snippets/popup-logic.liquid | The popup manager |
needHelpPopup | sections/need-help-popup.liquid | need-help-popup definition |
packOptions | snippets/pack-options-config.liquid | src/entrypoints/pack-options.ts |
selectOptionsModalConfig | sections/select-options-modal.liquid | src/entrypoints/select-options-modal.ts |
plpSegmentationTiles | sections/plp-segmentation-tiles.liquid | The segmentation tiles entrypoint |
The layout writes cartRewardBanner, so it is present on every page. cartTotal is in dollars, computed in Liquid as
the sum of final_price times quantity across lines without the __free_gift property, divided by 100. rewardTiers
comes from the four tiers in the Rewards Tiers settings group, skipping any tier with an empty title.
cartRewardBanner.instance holds either a CartRewardBanner or a HomepageProminenceBanner, depending on which
entrypoint ran for the current template. The two are separate classes with the same purpose, so check the type before
calling anything on it.
src/entrypoints/cart-reward-banner.ts converts cartTotal a second time. See the known discrepancy in
Legacy and unused code.
Labels and formatting
| Key | Contents |
|---|---|
moneyFormat, moneyWithCurrencyFormat | Shopify money format strings |
labels.addToCart | Add to cart button text |
labels.preorder | Pre-order button text |
labels.product_gift_skip_cta_label | Skip label in the gift promotion modal |
labels.klaviyo.trigger.button_label | Klaviyo trigger button text |
labels.medispa.remainingAmountLineItemLabel | Balance owing label on a booking line |
labels.medispa.remainingAmountLineItemValueTemplate | Template for that balance |
labels.medispa.depositAmount | Default deposit |
Money values from theme settings are in dollars. Money values from Shopify are in cents. Convert once, at the point of
display. src/entrypoints/utils.ts provides formatMoney, shopifyFormatCurrency and formatCentsInMoneyTemplate.
Page context
| Key | Contents |
|---|---|
pageType | Current template type |
productImageSize | Configured product image size |
searchMode | Search behaviour setting |
showPageTransition, showElementStaggering, showImageZooming | Animation switches |
Other globals the theme sets
These sit on window directly rather than under window.theme.
| Global | Purpose |
|---|---|
window.defer(fn, selector) | Run fn once selector matches, polling every 50 ms |
window.deferJS(fn, validator) | Run fn once validator() is true, polling every 50 ms |
window.enableLogging(value), window.disableLogging() | Debug logging switches |
window.popupMonitor | The popup manager instance |
window.popupTimer | The popup interval timer |
window.klaviyoSniffer, window.customSniffer | Popup detection |
window.PurchaseGiftManager | Multi-buy gift promotion logic |
window.miniCartGiftsConfig | Free gift configuration read from the metaobject |
window.addCheckoutEventChain(cb) | Register a callback that runs before checkout |
window.nativeFetch | The original fetch, captured before Yett and the cart interceptor patch it |
window.YETT_BLACKLIST | Script patterns Yett holds back |
The layout's first script tag captures window.nativeFetch. Use it when you need a request that neither Yett nor the
cart interceptor should see.
App globals the theme reads
These belong to installed apps. The theme waits for them rather than loading them.
| Global | App |
|---|---|
window.SesamiSDK | Sesami booking |
window._klOnsite | Klaviyo |
window._swat, window.SwymCallbacks | Swym wishlist |
window.StampedFn | Stamped reviews |
window.upez__chainEventManager | Upnova |
window.Currency | Currency conversion |
Every one of these can be absent. deferJS is the theme's usual way of waiting for one.
Adding a key
- Write it from Liquid.
<script>
window.theme = window.theme || {};
window.theme.myFeature = {{ my_value | json }};
</script>- Declare it in the
themeinterface insrc/@types/global.ts. - Read it defensively in TypeScript.
The interface ends with an index signature, so an undeclared key type checks. Declare it anyway, or every call site is
any and a rename goes unnoticed.