Set Up Hybrid Proxy Locally in Secondary Instance Group (SIG) Environments
Use the hybrid proxy Vite plugin to run Storefront Next and SFRA/SiteGenesis side by side at one origin during local development when connected to an on-demand sandbox. The steps in this documentation apply primarily to local development. At the end of this setup, you can navigate between Storefront Next and SFRA/SiteGenesis pages at http://localhost:5173 without visible redirects.
Hybrid proxy is for local development with a sandbox (ODS) only. It works only with pnpm dev and must not run in production.
For Managed Runtime (MRT) and production deployments, use Cloudflare eCDN origin routing between Storefront Next and SFRA/SiteGenesis.
Run Storefront Next and SFRA/SiteGenesis simultaneously at a single origin (localhost:5173) with no visible redirects or session loss. Navigate freely between Storefront Next pages and SFRA/SiteGenesis pages as if they were one unified storefront.
Routing decisions use the same Cloudflare eCDN expression format (http.request.uri.path matches) as your production configuration. Copy your HYBRID_ROUTING_RULES value from your eCDN origin rules, or keep it in sync with them, so local development routing matches production.
No assumptions are made about which pages live on Storefront Next versus SFRA/SiteGenesis. You define the split entirely through HYBRID_ROUTING_RULES. Any combination of migrated and legacy pages is valid; include only the routes you’ve built in Storefront Next.
A dedicated HYBRID_PROXY_ENABLED flag controls the proxy. It defaults to false, so the proxy doesn’t activate unless you explicitly turn it on. The plugin is also guarded by a mode === 'development' check in vite.config.ts, so the proxy doesn’t run in a production build.
Make sure that:
- You run your storefront with
pnpm dev. - You have access to an B2C Commerce sandbox that runs SFRA/SiteGenesis.
- You have the required storefront environment variables.
- You complete “Configure Business Manager” in Set Up Your Storefront with Hybrid Auth. Those Business Manager settings are also required when using the hybrid proxy.
These settings must be present in your .env for local development, and in your MRT environment variables for staging and production.
-
Copy the environment template if you haven’t already done so.
-
Enable hybrid mode.
-
Set
PUBLIC__app__hybrid__legacyRoutesto a JSON array of routes that belong to SFRA/SiteGenesis. When a user clicks a<Link>to one of these paths, the client-side navigation middleware forces a full-page load so the CDN routes the request to SFRA/SiteGenesis.OR
Supports exact paths and React Router-style parameterized patterns:
This list is the inverse of
HYBRID_ROUTING_RULES. If a route isn’t in your routing rules (SFRA/SiteGenesis owns it) and a Storefront Next page links to it, add it here. If it’s missing, React Router tries to render the route client-side and shows a 404.
These settings apply only to the Vite dev server. They have no effect in production builds.
-
Set
HYBRID_PROXY_ENABLED=true. -
Set
SFCC_ORIGINto the full HTTPS URL of your B2C Commerce sandbox. -
Set
HYBRID_ROUTING_RULESto define which paths stay on Storefront Next. -
Set
PUBLIC__app__defaultSiteIdso that the proxy can build SFRA/SiteGenesis-prefixed paths. The proxy fails fast at startup if this variable is missing whenHYBRID_PROXY_ENABLED=true. -
Optional: Set
HYBRID_PROXY_LOCALEif your SFRA/SiteGenesis locale path differs from your storefront fallback locale. -
Start the local development server with
pnpm dev.
The proxy is disabled by default in .env.default and only activates when HYBRID_PROXY_ENABLED=true.
Use HYBRID_ROUTING_RULES to define route ownership.
To compare route split patterns, see Choose a Hybrid Routing Matrix.
- Paths that match your expression go to Storefront Next.
- Paths that don’t match go to B2C Commerce (SFRA/SiteGenesis) via the proxy.
- Define any split between migrated and legacy pages. Include only the routes you’ve built in Storefront Next.
The rule syntax matches Cloudflare eCDN origin rules:
Combine clauses with or and wrap the expression in parentheses:
Include these patterns so React Router server endpoints continue to work:
| Pattern | Required for |
|---|---|
^/resource.* | React Router resource routes |
^/action/.* | React Router actions |
.*\.data.* | Production parity in shared rule sets |
Add patterns for Storefront Next pages that your team has already migrated:
| Pattern | Route |
|---|---|
^/$ | Homepage |
^/login.* | Login page |
^/logout.* | Logout |
^/signup.* | Registration |
^/reset-password.* | Password reset |
^/account.* | Account pages |
^/product.* | Product detail pages |
^/category.* | Category and PLP pages |
^/search.* | Search results |
^/social-callback.* | Social login callback |
This example keeps homepage, auth, product, category, search, account, and server endpoints on Storefront Next:
The proxy doesn’t forward these paths to B2C Commerce:
/@*,/__*(Vite internals)/src/*,/node_modules/*(Vite-served source files)*.data(React Router data requests)/mobify/*(SCAPI proxy paths handled by React Router)- Static assets (
.js,.css,.png,.woff2, and similar extensions)
The proxy always forwards SFRA/SiteGenesis static assets under /on/demandware.static/* and /on/demandware.store/* to B2C Commerce.
The hybrid proxy processes each development request in this order:
- Vite receives the request at
localhost:5173. - The hybrid proxy middleware evaluates the request path.
- If the path matches
HYBRID_ROUTING_RULES, React Router handles the request in Storefront Next. - If the path doesn’t match, the proxy forwards the request to
SFCC_ORIGIN. - For proxied storefront paths, the proxy rewrites to SFRA/SiteGenesis format:
/cart->/s/{siteId}/{locale}/cart
- The proxy rewrites response cookies and response body links for localhost continuity.
Hybrid auth requires that both Storefront Next and SFRA/SiteGenesis share the same session cookies (dwsid, cc-*). The proxy keeps them in sync in three ways:
-
Set-Cookie header rewriting (Layer 1): The proxy rewrites
Domain=.salesforce.comtoDomain=localhostin B2C Commerce response headers. The proxy preserves all other cookie attributes (Secure,SameSite,HttpOnly). Localhost is a secure context, soSecurecookies work onhttp://localhost. -
Storefront Next server cookies (Layer 2): Storefront Next sets its own session cookies (
dwsid, access token, refresh token, etc.) server-side via the auth middleware. Storefront Next writes them directly tolocalhost—they require no rewriting. The proxy doesn’t modify them. -
Client-side cookie interception (Layer 3)—localhost workaround only: The proxy injects an inline script at the top of every proxied HTML page. The script patches
document.cookieto apply the sameDomain=localhostrewrite to any cookies set by SFRA/SiteGenesis’s own JavaScript. SFRA/SiteGenesis’s client-side scripts checkwindow.location.protocolto decide whether to includeSecureon cookies—onhttp://localhostthey omit it, producing cookies the browser silently rejects. This layer exists solely to compensate for localhost’s non-HTTPS context and has no equivalent in the eCDN-based hybrid implementation used in production.
If a <Link> in Storefront Next navigates to an SFRA/SiteGenesis route and React Router shows a 404 or error boundary instead of the SFRA/SiteGenesis page, the route is probably missing from PUBLIC__app__hybrid__legacyRoutes.
Add the missing path to the array:
Set this variable in every environment—local development and production (MRT).
Keep HYBRID_ROUTING_RULES aligned with your Cloudflare eCDN origin rules. If they diverge, local behavior doesn’t match production routing.
If a Storefront Next path is missing from HYBRID_ROUTING_RULES, the request can fall through to SFRA/SiteGenesis and trigger SFRA/SiteGenesis redirects. The proxy logs a warning for SFRA/SiteGenesis 404 redirect patterns, for example:
Add the missing route pattern to HYBRID_ROUTING_RULES.
SFRA/SiteGenesis expects /s/{siteId}/{locale}/path. If HYBRID_PROXY_LOCALE doesn’t match your SFRA/SiteGenesis locale configuration, requests can return 404 responses or redirects.
The proxy rewrites response bodies after decompressing gzip, brotli, and deflate. If B2C Commerce returns another compression format, the proxy skips body URL rewriting.
The plugin runs only in development mode through the mode === 'development' guard in vite.config.ts.
We strongly recommend using the default shouldRouteToNext matcher. Overriding it means your local dev routing no longer mirrors the Cloudflare eCDN expression format used in production. Only do this if you have a specific reason and understand the divergence it introduces.
The default matcher (shouldRouteToNext) parses Cloudflare expression syntax. Use a custom matcher only when you intentionally diverge from production-style route expressions.
To replace the matcher entirely, use:
The callback receives pathname and routingRules. Return true to route to Storefront Next, or false to proxy to B2C Commerce.
If the matcher throws an error, the proxy fails safe and passes the request to React Router.