# Hybrid Storefront Routing Matrix

Use this routing matrix to choose a hybrid storefront split between Storefront Next and SFRA/SiteGenesis.

The examples in this guide apply to all hybrid setups:

- For local hybrid proxy setups, set `HYBRID_ROUTING_RULES` in your environment variables.
- For on-demand sandbox (ODS) and production setups, paste the same rule expression directly into eCDN routing rules.

## Use the Right Rule Syntax by Setup Type

Use the same expression pattern in every setup, but use different input formats:

- **Local hybrid proxy (`.env`)**: Assign the rule to `HYBRID_ROUTING_RULES` and wrap the expression in single quotes.
- **ODS and production (eCDN UI)**: Paste only the rule expression in **Rule expression**. Do not include `HYBRID_ROUTING_RULES=` and do not wrap the expression in single quotes.

Example for local hybrid proxy:

```bash
HYBRID_ROUTING_RULES='(http.request.uri.path matches "^/category.*" or http.request.uri.path matches "^/product.*")'
```

Example for eCDN:

```text
(http.request.uri.path matches "^/category.*" or http.request.uri.path matches "^/product.*")
```

## Architectural Foundations

1. `HYBRID_ROUTING_RULES`: A single Cloudflare expression used by the edge routing layer. The pattern supports both unprefixed paths and paths with a `/:siteId/:locale` prefix. Prefix values can be aliases or raw IDs.
2. `PUBLIC__app__hybrid__legacyRoutes`: A JSON array used by the Storefront Next client-side routing middleware to force a full-page navigation to SFRA/SiteGenesis routes.

The examples use the optional prefix pattern `^(/[^/]+/[^/]+)?`. The first segment matches any site value, and the second segment matches any locale value. Each value can be an alias or a raw ID, so the eCDN rule doesn't need an allowlist of every site-locale combination. If your application uses a different `url.prefix` shape, replace the entire sample prefix with a pattern for that shape.

For configurations where Storefront Next handles the Home route, use a separate Home expression: `^(/|/[^/]+/[^/]+/)$`. It matches `/` and a prefixed Home path such as `/us/en-US/`. When an exactly two-segment path represents prefixed Home, end it with a trailing slash; an unprefixed two-segment route must use its canonical form without a trailing slash, such as `/product/123`. This convention lets eCDN distinguish the two shapes without maintaining site and locale allowlists. The expression intentionally doesn't match `/us/en-US` or `/us/en-US/home`. Configure `url.prefix`, generated Home links, and SFRA/SiteGenesis redirects to use the canonical trailing-slash Storefront Next root.

:::important
A prefixed Home URL must end with a trailing slash, for example, `/us/en-US/`. Reserve the exactly-two-segment trailing-slash shape for prefixed Home; don't use that shape for an unprefixed two-segment route such as `/product/123`.
:::

## Matrix Configurations

Check out some examples of the different ways you can set up your hybrid storefront.

### Matrix-01: Modern Core (Home, PDP, PLP on Storefront Next)

- **Strategy:** The active customer discovery funnel, search, account, and social authentication routes run on Storefront Next. Only checkout (`/cart` and `/checkout`) stays on SFRA/SiteGenesis.
- **HYBRID_ROUTING_RULES:**

```bash
HYBRID_ROUTING_RULES='(http.request.uri.path matches "^(/|/[^/]+/[^/]+/)$" or http.request.uri.path matches "^(/[^/]+/[^/]+)?/(category|product|search|account|login|signup|logout|reset-password|social-callback)(/.*)?$" or http.request.uri.path matches "^/resource.*" or http.request.uri.path matches "^/action/.*" or http.request.uri.path matches ".*\.data.*" or http.request.uri.path matches "^/assets/.*" or http.request.uri.path matches "^/favicon\.ico$")'
```

- `PUBLIC__app__hybrid__legacyRoutes`:

```bash
PUBLIC__app__hybrid__legacyRoutes='["/cart", "/checkout"]'
```

### Matrix-02: Modern Checkout (Cart and Checkout on Storefront Next)

- **Strategy:** Use this split to test or roll out a Storefront Next checkout while keeping browse and discovery routes on SFRA/SiteGenesis.
- **HYBRID_ROUTING_RULES:**

```bash
HYBRID_ROUTING_RULES='(http.request.uri.path matches "^(/[^/]+/[^/]+)?/(cart|checkout)(/.*)?$" or http.request.uri.path matches "^/resource.*" or http.request.uri.path matches "^/action/.*" or http.request.uri.path matches ".*\.data.*" or http.request.uri.path matches "^/assets/.*" or http.request.uri.path matches "^/favicon\.ico$")'
```

- `PUBLIC__app__hybrid__legacyRoutes`:

```bash
PUBLIC__app__hybrid__legacyRoutes='["/", "/category/:id", "/product/:id", "/search", "/account", "/login", "/signup", "/reset-password"]'
```

### Matrix-03: Modern Entry Only (Home on Storefront Next)

- **Strategy:** Use this split during early pilots when only the home page is modernized and deeper flows remain on SFRA/SiteGenesis.
- **HYBRID_ROUTING_RULES:**

```bash
HYBRID_ROUTING_RULES='(http.request.uri.path matches "^(/|/[^/]+/[^/]+/)$" or http.request.uri.path matches "^/resource.*" or http.request.uri.path matches "^/action/.*" or http.request.uri.path matches ".*\.data.*" or http.request.uri.path matches "^/assets/.*" or http.request.uri.path matches "^/favicon\.ico$")'
```

- `PUBLIC__app__hybrid__legacyRoutes`:

```bash
PUBLIC__app__hybrid__legacyRoutes='["/category/:id", "/product/:id", "/search", "/account", "/login", "/signup", "/reset-password", "/cart", "/checkout"]'
```

### Matrix-04: Legacy Entry Only (Home on SFRA)

- **Strategy:** Use this split when the home page stays on SFRA/SiteGenesis, while deeper browse and transactional routes move to Storefront Next.
- **HYBRID_ROUTING_RULES:**

```bash
HYBRID_ROUTING_RULES='(http.request.uri.path matches "^(/[^/]+/[^/]+)?/(category|product|search|account|login|signup|logout|reset-password|social-callback|cart|checkout)(/.*)?$" or http.request.uri.path matches "^/resource.*" or http.request.uri.path matches "^/action/.*" or http.request.uri.path matches ".*\.data.*" or http.request.uri.path matches "^/assets/.*" or http.request.uri.path matches "^/favicon\.ico$")'
```

- `PUBLIC__app__hybrid__legacyRoutes`:

```bash
PUBLIC__app__hybrid__legacyRoutes='["/"]'
```

### Matrix-05: Catalog-Only Migration (PLP/PDP on Storefront Next)

- **Strategy:** Move high-volume catalog routes (category, product, search) to Storefront Next while preserving legacy account and checkout routes.
- **HYBRID_ROUTING_RULES:**

```bash
HYBRID_ROUTING_RULES='(http.request.uri.path matches "^(/[^/]+/[^/]+)?/(category|product|search)(/.*)?$" or http.request.uri.path matches "^/resource.*" or http.request.uri.path matches "^/action/.*" or http.request.uri.path matches ".*\.data.*" or http.request.uri.path matches "^/assets/.*" or http.request.uri.path matches "^/favicon\.ico$")'
```

- `PUBLIC__app__hybrid__legacyRoutes`:

```bash
PUBLIC__app__hybrid__legacyRoutes='["/", "/account", "/login", "/signup", "/reset-password", "/cart", "/checkout"]'
```

### Matrix-06: Account and Auth Only (Identity Flows on Storefront Next)

- **Strategy:** Move account and authentication experiences to Storefront Next while leaving catalog and checkout on SFRA/SiteGenesis.
- **HYBRID_ROUTING_RULES:**

```bash
HYBRID_ROUTING_RULES='(http.request.uri.path matches "^(/[^/]+/[^/]+)?/(account|login|signup|logout|reset-password|social-callback)(/.*)?$" or http.request.uri.path matches "^/resource.*" or http.request.uri.path matches "^/action/.*" or http.request.uri.path matches ".*\.data.*" or http.request.uri.path matches "^/assets/.*" or http.request.uri.path matches "^/favicon\.ico$")'
```

- `PUBLIC__app__hybrid__legacyRoutes`:

```bash
PUBLIC__app__hybrid__legacyRoutes='["/", "/category/:id", "/product/:id", "/search", "/cart", "/checkout"]'
```

## Global Framework Requirements

Keep these route clauses in every matrix configuration:

- `^/resource.*` and `^/action/.*` to avoid loop routing on modern layouts and handlers.
- `.*\.data.*` to prevent React Router 7 data prefetch requests from being routed to SFRA/SiteGenesis.
- `^/assets/.*` and `^/favicon\.ico$` for core Storefront Next static assets.
