Next.js multi-zones for independent team deploys, basePath and reverse proxy wiring, shared auth across zones, multi-tenant subdomain routing with per-tenant database isolation, and assetPrefix for tenant CDN origins.
A-10 — Multi-Zones, Multi-Tenant, and Distributed Architecture
Who this is for: Architects building applications that have outgrown a single Next.js codebase — either because different teams own different parts of the product (multi-zone), or because the same codebase needs to serve multiple customers with isolated data and custom domains (multi-tenant). This module covers the architectural patterns for both.
Multi-Zone Architecture — One Domain, Multiple Apps
A Next.js multi-zone deployment lets you host multiple independent Next.js applications on the same domain. Each application owns a path prefix, and a reverse proxy routes requests to the right app.
The canonical use case: a large organisation where the marketing site (/), the documentation (/docs), and the main application (/app) are maintained by different teams with different release cycles. Rather than forcing them all into one repository and one deployment, each is an independent Next.js app.
On Vercel, this is configured through the project settings as a "multi-zone" setup — each project gets a Vercel domain, and a rewrites config in the primary project routes traffic:
Each zone's next.config.ts sets a basePath so internal links resolve correctly:
Multi-Zone Constraints
Multi-zone has real constraints that trip up teams the first time they try it.
Client-side navigation between zones is not possible. The App Router's client-side navigation works within a single Next.js app. A link from the marketing zone to /docs/getting-started causes a full page navigation — the docs zone app boots fresh. There's no shared React tree between zones.
This is actually fine for the canonical use case (marketing → docs → app are all different products) but becomes a problem if you're trying to use multi-zone for micro-frontend architecture where seamless navigation is expected.
Shared layouts require duplication. If you want a consistent header across all zones, each zone must implement it separately. There's no "shared layout" that spans zones. The coordination problem is usually solved with a shared npm package for the header component.
Router Cache doesn't cross zones. Each zone has its own Router Cache. Navigating from the marketing zone to the docs zone clears the Router Cache.
When Multi-Zone Is the Right Choice
Use multi-zone when:
- Different parts of the site have legitimately different deployment cadences
- Different teams own different parts and shouldn't share CI/CD pipelines
- You're migrating from one architecture to another incrementally (old Pages Router app on
/legacy, new App Router app on everything else) - Bundle size and cold start time are affected by mixing concerns (a marketing site and a data-heavy application have very different dependencies)
Don't use multi-zone for:
- Micro-frontend architecture where seamless navigation is required
- Sharing significant state between zones
- Performance-critical flows that span zone boundaries
Shared Authentication Across Multi-Zones
Here's the question every team asks the first week they run multi-zone in production: a user logs in on the marketing zone (or the app zone, wherever the login form lives), then clicks a link that rewrites() sends to the docs zone. Are they still logged in?
By default, no. Each zone is a completely separate Next.js application with its own deployment, its own server, and — this is the part that catches people — its own idea of what a "session" is. If your auth library is configured per-zone with defaults, it'll set a cookie scoped however that zone's config says, and the other zone has no way to know the user is authenticated. The URL bar shows one unified domain, so users (reasonably) expect one unified session. What they get instead, if you haven't set this up deliberately, is being logged out every time they cross a zone boundary.
The fix is not "one zone owns the session and tells the others." There's no shared server-side session store that Next.js wires up for you across zones, and building a token-relay system between zones is more infrastructure than the problem needs. The actual pattern is simpler: every zone independently validates the same cookie.
That requires two things to line up across all zones:
- The cookie must be scoped to the parent domain, not a subdomain or a zone-specific path. A cookie set with
Domain=app.example.comis invisible to a request served fromdocs.example.comor evenexample.com/docsbehind a rewrite, depending on how the rewrite is set up. Set it at the registrable parent domain —Domain=.example.com— so every zone sitting underexample.comcan read it. - Every zone must run the identical verification logic against the identical secret. If zone A signs session tokens with
AUTH_SECRET=fooand zone B is configured withAUTH_SECRET=bar(or worse, a totally different auth library), zone B can't verify a cookie zone A issued. Zone B isn't "asking zone A if this user is logged in" — it's independently checking the token's signature, and it can only do that if it has the same key.
Sign in to keep reading
The rest of this module is free — sign in with Google to unlock it and track your progress.
Sign in & RegisterDiscussion
0Join the discussion