How it works

Multitenancy, handled at the framework level

Every request is routed to the right tenant before a single byte of HTML is rendered. Here's the full lifecycle.

01

Request hits the edge

A visitor opens acme.myesite.shop. Next.js reads the Host header before any page renders.

02

Tenant is resolved

The subdomain (acme) is matched against your tenant registry — a DB lookup in production, cached at the edge.

03

Traffic is rewritten

The request is rewritten to /_sites/acme/* internally. The URL the user sees never changes.

04

Themed site renders

The tenant's content and theme load from a shared design system. One codebase, infinite brands.

The whole router is one file

Middleware reads the host, resolves the tenant, and rewrites the request. No per-tenant builds, no duplicated infra.

Start building
export default function middleware(req) {
  const host = req.headers.get("host");
  const sub = host.split(".")[0];

  // acme.myesite.shop -> /s/acme
  return NextResponse.rewrite(
    new URL(`/_sites/${sub}${req.nextUrl.pathname}`,
      req.url)
  );
}

Built for scale

Wildcard subdomains

*.myesite.shop routes to the right tenant automatically.

Custom domains

Map acme.com to a tenant with a single CNAME and verified TXT record.

Per-tenant theming

Colors, logos, and fonts driven by tenant config, not forks.

Row-level isolation

Every query is scoped to the active tenant slug by default.

Edge-cached lookups

Tenant resolution adds under 40ms at the 99th percentile.

Instant onboarding

Create a tenant via API and it's live immediately — no deploy.