Which store, and its URLs
How the engine decides which store a request is for, which hosts may name one, and the store segment on localhost.
One theme serves many stores at once. The same build answers perfumes.example, furniture.example and every other merchant domain that installs it, so which store a page is for is decided on every request, never by your code or configuration.
The rules differ between a merchant's own domain and the hosts that serve many stores. Step through the decision.
1. A request arrives
A request carries three things that could say which store it is for: the host name (perfumes.example), the path (/cart) and its cookies. Which of them the engine believes depends on the host.
In engine terms
twilightMiddleware() reads the host with requestHostOf(request) (src/utils/request-host.ts): the request URL's host, else the Host header. Never X-Forwarded-Host, which a client can set.
The two kinds of host
| Host | May the request name a store? | The store is | /cart means |
|---|---|---|---|
| A merchant domain (any host not below) | No | The host itself | The cart page |
preview.salla.design | Yes | ?storeId=, then the first path segment, then the cookie | The store whose username is cart |
localhost, 127.0.0.1, [::1], *.localhost | Yes | The same, then VITE_STORE_DOMAIN | The store whose username is cart |
See what this page resolves
import { resolveStoreIdentifier } from '@salla.sa/twilight-theme-engine/api/store';
// '' means nothing resolved: every Salla API call would fail with 422.
const storeIdentifier = resolveStoreIdentifier();
Why a theme never pins a store
- A store id in code (or a
store-identifieryou set on every request) makes every merchant's domain show that one shop. Let the request decide; pass an explicit identifier only when your code already knows which store it is asking about. - `VITE_STORE_DOMAIN` is not configuration. It is a build-time value for
pnpm dev, and it is consulted last. On a deployed theme the host answers first. - `?storeId=` on a merchant domain does nothing, by design. Test store switching on localhost or the preview host.
- A path built from the address bar gets the store segment twice on localhost and the preview host (
/dev-x/dev-x/cart), because the router adds it again. Use the engine'sLink,useNavigateanduseLocation.
Go deeper: resolveStoreIdentifier, getStoreIdentifier, twilightMiddleware, createRouter, Link and useLocation.