Skip to content

fix: resolve slug kind before fetching product detail - #2

Open
kalwiggins wants to merge 1 commit into
mainfrom
fix/slug-resolution-order
Open

fix: resolve slug kind before fetching product detail#2
kalwiggins wants to merge 1 commit into
mainfrom
fix/slug-resolution-order

Conversation

@kalwiggins

Copy link
Copy Markdown
Contributor

Fixes the source of a defect that has now propagated into every storefront generated from this template.

The problem

In the catch-all [slug] route, every category and brand page view fires a guaranteed-404 product lookup first — twice per request, once in generateMetadata and once in the page. In this template that costs little, because the default repositories read bundled JSON. In a downstream storefront with a live backend wired in, each one becomes a real API call.

Measured on RVGearPro, generated from this template and pointed at Foundry — one hour of CloudFront access logs:

6,703 of 6,709 storefront requests were 404s
127 unique paths, 53:1 repeat ratio
all shaped /products/<category-slug>
user-agent "node"  ← the storefront's own server-side fetches

~99.8% of its catalog API traffic achieved nothing, and each 404 was a real database query at the origin.

Root cause

The resolution order is backwards relative to cost:

Lookup Cost
categoryRepository.getBySlug cached list → in-memory find, no network
brandRepository.getBySlug cached list → in-memory find, no network
productRepository.getBySlug live backend call once a real provider is wired in

The expensive question was asked first, unconditionally.

The fix

resolveSlugKind() asks the two free questions first and falls through to "product" only when the slug is neither — where a miss is a genuine 404. Both entry points share it, so the work happens once per request instead of twice.

The diff is deliberately small: one line per branch, all rendering and SEO bodies untouched.

Precedence change

A slug matching both a category and a product now resolves to the category, where it previously resolved to the product. Preserving the old precedence would require always paying for the product lookup, which is the cost being removed. Flagging it because it is a behaviour change, not a pure optimization.

Downstream

Existing storefronts do not inherit this automatically — each was generated, not linked. The same fix has been raised separately against the ones with a live backend (Foundry, MiniPIM or BigCommerce). Storefronts wired only to static JSON were deliberately skipped: there is nothing to save there.

This PR stops future generated storefronts being born with it.

Verification

tsc --noEmit reports no errors in the changed file.

The catch-all [slug] route asked the expensive question first: every category
and brand page view fired a guaranteed-404 product lookup, twice per request
(generateMetadata and the page). Cheap here, where the default repositories
read bundled JSON -- but a real API call in any storefront generated from this
template with a live backend wired in.

Measured on RVGearPro, generated from this template and pointed at Foundry:
in one hour of CloudFront access logs, 6,703 of 6,709 catalog requests were
exactly this, each one a real database query at the origin.

categoryRepository.getBySlug and brandRepository.getBySlug resolve against a
cached list -- an in-memory find, no network. productRepository.getBySlug is
the live call. So ask the free questions first and only pay for the product
lookup when the slug is neither, where a miss is a genuine 404.

Precedence change: a slug matching BOTH a category and a product now resolves
to the category. Preserving the old precedence would mean always paying for
the product lookup, which is the cost being removed.

Existing storefronts do not inherit this -- they were generated, not linked --
and are being fixed separately. This stops future ones being born with it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant