SEO URL Rules Best Practices for Storefront Next
Deterministic SEO URLs let Storefront Next infer a URL’s content type (product, category, or content) and fetch that content directly from the path, with no getUrlMapping call to resolve the URL. That keeps routing decisions fast and URL patterns predictable, which improves SEO. This guide outlines best practices for configuring SEO URL rules in Storefront Next and Business Manager.
These best practices suggest some ways to configure SEO URL rules. Other SEO URL configurations can work depending on your needs. These suggestions are subject to change.
Business Manager defines a site’s SEO URL grammar: the product URL prefix, the category URL prefix, whether category URLs carry the category ID or a pure slug path, and the optional content prefix. Business Manager enforces the URL requirements and serves as the canonical configuration for your B2C Commerce instance. Storefront Next mirrors those settings so its generated URLs stay consistent with the rest of your commerce ecosystem.
- Define the URL structure in Business Manager. See Configure SEO URLs for B2C Commerce in Salesforce Help.
- Mirror that structure in Storefront Next with the
seoRoutesconfiguration (see ConfigureseoRoutes). You do not rename route files to match the grammar. - Test URLs in both environments to verify consistency.
Storefront Next generates product and category URLs from per-site seoRoutes configuration in config.server.ts, keyed by Commerce site ID. Each site defines a product prefix, a category prefix, a category mode, and an optional content prefix.
product.prefixandcategory.prefixare static path segments without slashes (for examplep,c,product,category).category.modeisid-suffixorslug-path(see URL Guidance for Categories).content.prefixis optional and reserved for standalone content URLs.
With seoRoutes set, a product URL is /{siteId}/{localeId}/{product-prefix}/{slug}/{id} and a category URL follows the category mode. Generate these URLs with the semantic builders (createProductUrl, createCategoryUrl, and createCategoryUrlFromLegacyPath) rather than hard-coded paths. The builders return the functional path (such as /{product-prefix}/{slug}/{id}) and encode each segment; the template’s Link and navigation wrappers add the /{siteId}/{localeId} prefix. Route server-side redirects and plain anchors through the same context-aware builders and wrappers, or they generate an unprefixed URL. The builders make no SCAPI or getUrlMapping call.
Adopting seoRoutes doesn’t rename, move, or split any file in src/routes/. The canonical _app.product.$productId.tsx and _app.category.$categoryId.tsx modules stay where they are. At build time each becomes a parent that owns its configured prefix, so the configured URLs route back to the same loader and component. Both modules must remain leaf routes (no nested child routes) when seoRoutes is enabled, or the build fails.
When seoRoutes is set, every active site must have an entry. The storefront compiles the union of every site’s prefixes into its route manifest and drops the built-in /product/{id} and /category/{id} routes, so a site with no entry can’t generate product or category URLs. Treat seoRoutes as an all-sites decision, not a gradual per-site rollout.
seoRoutes is a protected configuration value: it is compiled into the route manifest and cannot be overridden with a PUBLIC__ environment variable at runtime. When you change a URL setting in Business Manager, update config.server.ts to match, then rebuild and redeploy. Storefront Next doesn’t pick up the change automatically.
Automatic synchronization between Business Manager and Storefront Next is a planned enhancement. Until it ships, treat every Business Manager URL-setting change as a storefront configuration change that requires a rebuild and redeploy.
When you configure URL rules for products, we recommend that the URL:
- Includes this prefix:
/p/. - Ends with the product ID. Storefront Next reads the ID from the final path segment and fetches product data directly, with no extra API call to resolve the URL.
- Includes an identifiable slug before the ID. Product slugs are optional because the ID stays authoritative, but a readable slug improves SEO. Product search and search-suggestion responses already include the slug, so tiles, typeahead, and structured data use it without an extra request.
The seoRoutes grammar Storefront Next generates has no file extension. If your Business Manager URL rules or already-indexed URLs use an .html suffix, redirect the .html form to the suffix-less canonical URL with a 301 (see Prevent Broken Indexed URLs).
category.mode decides how a category URL resolves, and each mode has a prerequisite:
| Mode | URL shape | How it resolves | Prerequisite |
|---|---|---|---|
id-suffix | /c/{slug}/{id} | Reads the category ID from the final path segment. Deterministic, no getUrlMapping call. | Category ID present as the final segment. |
slug-path | /c/{full-slug-path} | The final segment is a slug, not the ID. Storefront Next doesn’t translate the slug back to an ID. | A slug-to-ID data source you supply for the site. |
We recommend id-suffix mode: it keeps category resolution deterministic and requires no additional data source.
As with products, the category slug is optional in id-suffix mode. The trailing ID is authoritative, so the storefront also generates slug-less /c/{id} URLs. Include a slug when one is available for better SEO.
In slug-path mode the category URL carries no ID, so Storefront Next cannot resolve it from the path alone. Until you supply a slug-to-ID data source for the site, keep the site in id-suffix mode. A pure slug path produces cleaner URLs but depends on that data source.
Standalone content URLs use the optional content.prefix.
The content.prefix is reserved. Storefront Next validates its format and guards it against collisions with the product and category prefixes, but it doesn’t yet check it against static app routes (such as account), and it doesn’t yet register a content route, so a content.prefix URL is not served on its own. Set it to reserve the grammar now; content routing is a planned enhancement.
When you configure URL rules for content pages, we recommend that the URL:
- Includes a content prefix such as
/content/. - Includes a content ID or an identifiable slug.
Changing a product or category prefix changes every already-indexed URL for that resource. Roll the prefix change and its redirect rules out together, and handle the transition at the CDN or Business Manager redirect layer, not in the storefront.
- Redirect the old grammar to the new with a single 301. Map the previous URL form to the new one (for example
/product/{id}to/p/{slug}/{id}). A 301 preserves the page’s ranking and keeps inbound links working. - Redirect once, directly to the canonical URL. The canonical URL is the one the storefront now generates. Don’t chain redirects, and do not let the new URL redirect back toward the old form. Either one creates a redirect loop that crawlers penalize.
- Handle
.htmlsuffixes. If legacy Commerce URLs ended in.html, redirect the.htmlform to the suffix-less canonical URL with a 301. Don’t serve both. - Match the canonical tag to the redirect target. Each page’s
<link rel="canonical">must name the same URL the redirects point at. See SEO and Metadata. - Regenerate sitemaps. Sitemap entries must use the new prefixes and contain no legacy-grammar URLs.
In a hybrid storefront, some paths are served by Storefront Next and some by the existing Commerce (SFRA or SiteGenesis) storefront. seoRoutes governs only the product and category paths Storefront Next owns.
- Storefront Next generates and serves SEO URLs for the sites and paths it owns.
- Paths owned by the legacy storefront keep their Commerce-managed URLs.
seoRoutesdoes not rewrite them. - An inbound URL that matches neither the new grammar nor a redirect rule falls through to the terminal Shopper SEO fallback. For an eligible GET or HEAD request, Storefront Next makes one Business Manager Shopper SEO URL Mapping lookup and, on a hit, redirects to the mapped product, category, or URL destination. A mapping miss, a rejected result, or an ineligible request returns a 404, and in a hybrid deployment a legacy-owned path is left for the legacy storefront. External redirect origins and forwarded query parameters are denied unless you allow them per site in the fallback policy. Still confirm your redirects direct legacy-owned URLs to the storefront that serves them.
Market Street, the retail reference storefront, uses short prefixes and deterministic id-suffix category routing:
Products resolve at /{siteId}/{localeId}/p/{slug}/{id} and categories at /{siteId}/{localeId}/c/{slug}/{id}. Copy this shape per site, and remember that every active site needs its own entry before you enable seoRoutes.