One Codebase.
Many Client Sites.
The hostname decides which tenant's content, theme, and navigation a visitor gets. Everything else is shared.
What it does
Hostname routing
Middleware maps the subdomain to a tenant slug, so acme.example.com and beta.example.com serve different content from one deployment.
Per-tenant theming
Colors, logo, and navigation come from one registry entry per tenant, applied as CSS custom properties rather than forked components.
MDX content
Pages are MDX files with Zod-checked frontmatter. Navigation is built from those files, so adding a page adds a nav entry.
Identity gating
Put a tenant behind Cloudflare Access and the app reads the signed-in email from the request headers. It never handles sign-in itself.
Edge rendering
Astro 4 in SSR mode on Cloudflare Pages Functions, so pages render at the edge close to the visitor.
Tenants
Tenants on this deployment are served from their own subdomains and resolved from the
request hostname. The ?as=<slug> override is not available here — it
works on localhost, and on a *.pages.dev host only when
ALLOW_TENANT_OVERRIDE=true is set.
Run it yourself
Clone it, install, and run. No environment variables required.
git clone https://github.com/keyanfayaz/client-sites.git
cd client-sites
pnpm install
pnpm dev
Check out the README for full documentation.
Preview deployment detected. Robots are blocked via X-Robots-Tag: noindex.