Overview

A theme in Commmerce is the bundle of pages, sections, elements, breakpoints and Global Settings that defines a complete storefront. Installation creates a draft Store Theme in your store, seeds it with the theme's blocks + settings + storefront preferences, and drops you straight into the visual editor on the Home page.

There are two install surfaces, depending on where the theme came from:

  • Seed themes — bundled with the platform; available from the Online Store empty state and the Themes marketplace page. One-tap install, no pre-customisation.
  • Marketplace themes — published by developers as theme apps via the Dev Portal; installed from the Explore Apps page through the Theme Installation screen, which lets a merchant customise branding, colours, typography, product display and SEO before committing.

Seed themes

Seed themes ship inside the platform build and load lazily — the ~1.9 MB theme JSON is only fetched when the merchant actually confirms the install, so the marketplace page itself stays light. Source of truth is common/constant/seedThemes.ts; the JSON payloads live under common/craft-collections/themes/.

ThemeIndustryStatusPreview & use case
Clash LoveFashionpopularclashlove.commmerce.com — full Fashion storefront with hero slider, product grid, blog and full cart/checkout. The canonical reference theme used by docs examples.
FrostedgeLuxury & Premiumnewfrostedge.commmerce.com — minimal, monochrome palette for high-ticket brands.
GloworaCosmetics & Skincarenewglowora.commmerce.com — pastel palette, hero collection blocks, ingredient-led PDP layout.

Install flow — Online Store empty state

For brand-new stores with no themes installed. The Online Store page (in your store dashboard) renders a starter grid of the seed themes. Picking one shows a confirmation dialog, then runs the install.

Walk-through

  1. Pick a starting variant on the Online Store page — Clash Love, Frostedge, or Glowora.
  2. Confirm in the modal — antd's static Modal.confirm doesn't render under React 19, so a controlled <Modal> is used; cancelling while installing is blocked.
  3. Theme data fetches lazily via loadSeedThemeData(variant) — dynamic import() of the matching JSON in common/craft-collections/themes/.
  4. Create Theme call ships theme_name, theme_slug, theme_image, blocks, block_mappings, settings (Global Settings overrides), and preferences (navigationMenus, passwordProtection, comingSoon).
  5. Verification — the page then re-fetches the installed-themes list and checks the new store_theme_id is present before redirecting; this surfaces partial-insert or replication-lag errors cleanly instead of dropping the merchant into a broken editor.
  6. Redirect — on success, the page navigates to /theme/<storeId>/<store_theme_id>/<store_theme_version_code>/<block_id>/<block_version_code> opening the editor on the Home page of the new theme.

Install flow — Themes marketplace

The Themes page (under Online Store → Themes) is the same seed-theme list with an Industry filter and a Sort-by control. Useful for merchants who already have a theme installed but want to try another seed without going through the Dev Portal app pipeline.

Differences vs. the Online Store flow

  • Always accessible — Online Store only shows the seed grid when there are zero installed themes; Themes lets you install another seed on top of an existing live theme (it lands as a draft).
  • Filterable — industry filter narrows to Fashion, Luxury, Cosmetics, etc; "Best Selling" is the default sort.
  • Identical install pipeline — same lazy seed-JSON load, same Create Theme call, same verification + redirect logic.

Install flow — marketplace themes

Marketplace themes are full apps published via the Dev Portal with app_type === "theme". From Explore Apps, picking a theme app opens the Theme Installation fullscreen page — common/components/theme-installation/ThemeInstallationPage.tsx — so the merchant can review and customise the theme before it lands in their store.

The page is a two-panel layout built on antd's Splitter: preview on the left (default 60%, min 30%, max 75%) and configuration on the right. Every settings edit re-renders the preview live.

Walk-through

  1. Browse apps on the Explore Apps page — the type filter pill is set to Theme.
  2. Pick a theme — Theme Installation opens fullscreen with a top bar showing the theme image + name, a Back arrow, and an Install Theme button.
  3. Review the preview on the left pane:
    • Device toggle — XL (120rem), Desktop (80rem), Tablet (48rem), Mobile (26.875rem).
    • Page picker — fetches the theme's page list and lets you cycle through Home, PDP, Cart, Checkout, etc.
    • Live preview pipes the BaseNode tree through jsonToHtmlCss and renders inside a sandboxed iframe with the SDK loader injected.
  4. Customise in the right pane — five tabs (see Pre-install configuration below); every change writes to a draftSettings object held in component state, never to the server.
  5. Click Install Theme — the button flips to Installing….
  6. Install call ships app_id, app_version_id (selected version or latest), theme_name, theme_slug and theme_image.
  7. Settings sync — on success, importSettings(draftSettings) commits the draft into the in-memory editor settings store, then saveStoreThemeVersionSettings persists them against the new store_theme_id / store_theme_version_code.
  8. Toast + close — "Theme <name> installed successfully!" and the page calls onInstalled() which closes the screen and refreshes the parent list.

Pre-install configuration

The right pane of Theme Installation hosts the same setting components used by the editor's Global Settings panel — so the merchant gets the full editor UI before any data lands in their store. All edits live in draftSettings and only persist if the user actually clicks Install.

TabComponentConfiguresWhy a merchant would change it
BrandingBrandingSettingsprimaryLogo, faviconIcon, brandLogoDrop in the merchant's primary logo (image or text) and favicon BEFORE the storefront ever paints — so the merchant doesn't see the theme's placeholder branding even on first load. The brand-logo text defaults to the app_name.
Theme ColourThemeColourSettingstext, button, addToCartButton, seeOrSelectVariantButton, border, inputBox, hyperlink, checkbox, radioButtonRepaint the theme to match the merchant's brand palette — primary/secondary text colours, button fills, hover states, border radius. Every web component reads these tokens so the change propagates to every page.
TypographyTypographySettings11 role-keyed stylesSwitch from the theme's default font stack to the merchant's brand font without re-uploading anything. The 11 roles (heading, subHeading, description, button, addToCartButton, seeOrSelectVariantButton, link, caption, label, sellingPrice, originalPrice) cover every text surface.
ProductProductSettingsbackgroundColor, productMediaWidth/Height/ObjectFit, shortDescription, descriptionTune product card / PDP media sizing so the merchant's actual product photography crops correctly the first time.
SEOSEOSettingsdefaultTitle, prefixTitle, suffixTitle, defaultDescription, defaultKeywords, defaultMetaImagePre-fill theme-wide SEO defaults so every page ships with branded title and description out of the gate. Per-page Block Settings can still override.

What gets created in your store

  • Store Theme row — a new store_theme in draft status with the bundled name, slug, and image. Lands alongside any existing draft + live themes (live theme is unaffected).
  • Block versions — every page, dialog, component, header, and footer in the seed JSON gets a row in block_version with display_order preserved.
  • Block mappings — parent-child references between blocks (e.g. footer-menu inside footer) materialise as app_block_mapping rows so the SSR layer can resolve them at render time.
  • Global Settings — the seed theme's settings JSON (or the merchant-customised draftSettings for marketplace installs) is persisted as the new theme version's settings record.
  • Storefront preferences — navigation menus, password protection, and coming-soon defaults from the seed payload are uploaded to GCS and the URL written to stores.preferences_url. This overwrites any existing preferences for the store — each theme bundles its own nav menu tied to its layout.
  • Page routes — Home (/) and any other page slugs in the seed are registered in app_page_routes so the SSR router can serve them.
  • Editor URL — the merchant is redirected to /theme/<storeId>/<store_theme_id>/<store_theme_version_code>/<block_id>/<block_version_code>, opening the editor on the Home page of the new draft theme.

Going live

Installation always creates a draft theme — your existing live theme keeps serving customers untouched. To swap which theme renders for visitors:

  1. Open Online Store → Themes and find the draft theme card you want to publish.
  2. Click Set live. The set-live action flips the store_theme row's status to live and demotes the previously-live theme to a draft. No content is destroyed; you can switch back at any time.
  3. Refresh your storefront. The CDN / Redis cache is invalidated for the affected pages so the new theme paints on the next request.

See the Publish page for the full publish + set-live flow at the editor level.

Tips & gotchas

  • Pre-install settings only apply once. The right-pane configuration is committed to the new theme version on install. Subsequent edits happen inside the editor's Global Settings panel against the same record.
  • Preferences overwrite is per-store, not per-theme. Installing a theme replaces the store's navigation menus / password protection / coming-soon settings entirely. If you've hand-built a custom nav menu, export the preferences JSON before installing a new theme.
  • Verification step protects against partial inserts. If the verify call doesn't find the new theme in the installed list (replication lag, partial DB write), the install flow surfaces a clear error on the install page instead of redirecting into a broken editor.
  • Theme Installation uses the same parser as the editor. The preview iframe runs the seed theme's BaseNode tree through jsonToHtmlCss with the user's draftSettings applied — pixel-identical to what the editor will render after install.
  • App-as-block install is separate. Non-theme apps from Explore Apps install as reusable blocks (header, footer, dialog, component) into the active theme — they don't seed a fresh store_theme row.
  • App version selection matters. Marketplace themes can ship multiple published versions. selectedVersionId wins over the app's app_version_id; default is the latest published version.