Storefront setup
Configuration
The per-deployment environment variables that set the storefront's languages, Home page, look, checkout and tracking behaviour.
Most of what shoppers see is managed in WordPress and changes without a redeploy. A few structural choices are made per deployment instead, with environment variables: which languages the store speaks, which Home page sections appear, the Template Family, and how checkout and tracking behave. This page groups those variables by what they change. Every variable, including the core and connection ones, is listed in Environment variables.
How to set a variable
Section titled “How to set a variable”| Where the storefront runs | Where to set it | When it applies |
|---|---|---|
| Your machine | apps/storefront/.env |
Restart pnpm dev |
| Cloudflare Workers | Cloudflare dashboard, on the Worker’s Settings → Variables and secrets | The next deployment |
| Any Node host | The service’s environment, or an .env file beside the app |
Restart the server |
Languages
Section titled “Languages”STOREFRONT_LOCALES=en,arSTOREFRONT_LOCALES is an ordered, comma-separated list of Locales.
- The first Locale is the default and is served without a prefix (
/shop). Every other Locale lives under its own prefix (/ar/shop). - With more than one Locale, a language switcher appears in the header. With one, there is no switcher and no prefix.
- Arabic, Persian, Hebrew and Urdu switch the layout to right-to-left automatically.
- An empty or invalid value falls back to English only. It never stops the store from starting.
- Default:
en.
English and Arabic ship complete. Adding another language means adding its translation files to the codebase, which is a developer task (see Languages and RTL).
Translated catalogue content
Section titled “Translated catalogue content”The Locale list translates the storefront’s own interface. To get product names, descriptions and categories in each language too, run WPML or Polylang in WordPress and tell the storefront which query parameter the plugin reads:
WOO_MULTILINGUAL_PARAM=langUnset, catalogue content stays in the store’s single content language.
Home page sections
Section titled “Home page sections”HOME_SECTIONS chooses which sections the Home page shows and in what order. Leaving a section out also skips the backend reads it would have made, so a shorter Home page is a cheaper one.
HOME_SECTIONS=hero,new-arrivals,todays-deals,callout| Section id | What it shows |
|---|---|
hero |
The hero slider managed in WordPress, or a branded static hero when the slider is off |
categories |
“Shop by category”: the categories with the most products |
new-arrivals |
The newest products |
season-sale |
A sale banner beside a grid of discounted products |
best-sellers |
A rail switching between best-selling and top-rated products |
todays-deals |
Products whose scheduled sale ends today, with a countdown to midnight in the store’s timezone |
brands |
A logo wall of brands, featured brands first |
trending |
Category cards ranked by what is selling |
callout |
A limited-time call-to-action panel |
recently-viewed |
The shopper’s recently viewed products |
promo-banners |
Promo cards with a badge, heading, discount and button |
daily-essentials |
The products marked Featured in WooCommerce |
reviews |
A wall of curated customer testimonials |
blog |
The latest blog posts |
- Unset, all 14 sections render in the order shown above.
- Unknown or repeated ids are dropped with a warning in the server log. A value that names no known section falls back to the full list.
- A section with nothing to show hides itself, whatever the list says.
What each section displays is managed in WordPress; see Home page.
Rail and row sizes
Section titled “Rail and row sizes”HOME_PRODUCT_CAROUSEL_LIMIT=12HOME_CATEGORIES_LIMIT=12| Variable | What it caps | Default |
|---|---|---|
HOME_PRODUCT_CAROUSEL_LIMIT |
Products in each Home product rail | 12 |
HOME_CATEGORIES_LIMIT |
Categories in the “Shop by category” row | 12 |
Both take a whole number from 1 to 100. Anything else logs a warning and uses the default. They are ceilings: a collection with fewer items shows what it has.
STOREFRONT_TEMPLATE_FAMILY=defaultA Template Family sets the store-wide design of the Home, listing and product pages, plus the default header and footer layout. Only default ships today. An unknown name is not ignored: pages fail with an error that lists the available families, so a typo shows up on the first page you open. Colours, logo, header and footer are set in WordPress, not here; see Theming and layout.
Checkout
Section titled “Checkout”DISTRUCTION_FREE_CHECKOUT=onWhen on, checkout and the order confirmation page drop the full header and footer for a logo-and-search header and a copyright-only footer, so shoppers stay focused on paying. It accepts on, true, 1 or yes, in any case. Anything else, including unset, leaves the full chrome in place.
Tracking and marketing
Section titled “Tracking and marketing”Header and footer scripts
Section titled “Header and footer scripts”STOREFRONT_CUSTOM_SCRIPTS=offThe Store Owner pastes tag managers, pixels and chat widgets into WordPress, and the storefront injects them on every page except the payment pages. Set this to off on staging, preview and local deployments so test visits never reach the live analytics. It also accepts false, 0 or no. Leave it unset in production. See Scripts and promo popup.
First-order promo popup
Section titled “First-order promo popup”NEXT_PUBLIC_PROMO_MODAL=00 turns off the first-order promo popup for this deployment, whatever WordPress says. Any other value, or unset, leaves the decision to the Store Owner’s setting in WordPress. The popup only ever shows to guests.
Share on Messenger
Section titled “Share on Messenger”NEXT_PUBLIC_FACEBOOK_APP_ID=1234567890A Facebook App ID enables the Messenger option in the product page’s share dialog. Empty, Messenger is hidden and the other networks still work. This is a public App ID for sharing only; Facebook sign-in is configured separately in WordPress.
Backend requests
Section titled “Backend requests”These tune how the storefront talks to WooCommerce. Most stores never touch them.
| Variable | What it does | Default |
|---|---|---|
WOO_REQUEST_TIMEOUT_MS |
How long one request to the store may take, in milliseconds. If a checkout times out, the storefront asks WordPress whether the order was placed before letting the shopper pay again. | 30000 |
WOO_CONNECT_TIMEOUT_MS |
How long to wait for a connection to the store, in milliseconds. Raise it if your WordPress sits behind a CDN that throttles connections. Node hosts only. | 30000 |
WOO_DEFAULT_PER_PAGE |
Page size when a request does not ask for one. | 20 |