Storefront

One application. Every partner.

Below are 5 storefronts. They are the same Next.js application, the same components and the same routes, resolved to a different partner per request. What differs is a partner row and a DNS record — there is no per-partner build, route file or component anywhere in this repository.

Storefronts
5
Backed by live data
0
Storefront applications
1

The same component, re-skinned

One ItemCard, identical props, rendered once per theme. Everything that changes below — colour, radius, type, spacing — arrives as CSS custom properties from the theme scope the card happens to sit in.

Each storefront, as itself

Real chrome, real search field, real catalogue. A theme with no partner behind it still renders — it simply has nothing to sell yet.

Theme onlyhoudini.shop-dev-v2.recrql.com:3000

No partner in the API answers to this slug yet — the theme renders regardless, which is the point: the storefront is one application and the partner is data.

Density
compact
Radius
2px
Type scale
×1.333
  • Accent
  • Accent soft
  • Surface
  • Ink
Theme onlykappahl.shop-dev-v2.recrql.com:3000

No partner in the API answers to this slug yet — the theme renders regardless, which is the point: the storefront is one application and the partner is data.

Density
comfortable
Radius
999px
Type scale
×1.25
  • Accent
  • Accent soft
  • Surface
  • Ink
Theme onlyoutnorth.shop-dev-v2.recrql.com:3000

No partner in the API answers to this slug yet — the theme renders regardless, which is the point: the storefront is one application and the partner is data.

Density
comfortable
Radius
4px
Type scale
×1.25
  • Accent
  • Accent soft
  • Surface
  • Ink
Theme onlypartner-0.shop-dev-v2.recrql.com:3000

No partner in the API answers to this slug yet — the theme renders regardless, which is the point: the storefront is one application and the partner is data.

Density
comfortable
Radius
8px
Type scale
×1.25
  • Accent
  • Accent soft
  • Surface
  • Ink
Theme onlybase.shop-dev-v2.recrql.com:3000

No partner in the API answers to this slug yet — the theme renders regardless, which is the point: the storefront is one application and the partner is data.

Density
comfortable
Radius
8px
Type scale
×1.25
  • Accent
  • Accent soft
  • Surface
  • Ink

How a request finds its partner

  1. Host header. A partner’s own storefront_domain resolves to its slug, so its URLs carry no prefix at all. In development the same rule reads <slug>.localhost:3000, which needs no /etc/hosts entry.
  2. Path. /p/<slug>/… names a partner explicitly. It is how this page opens every storefront from one hostname.
  3. Default. Anything that named no partner falls back to NEXT_PUBLIC_DEFAULT_PARTNER.

All three are decided once, in middleware, and passed on as request headers. Which partners exist, what they are called and which theme each one wears all come from GET /partners/ — the frontend holds no list of them.