Build Scalable Next.js SaaS Apps with Subdomain Multi-Tenancy

What is Multi-Tenant Architecture?
Multi-tenancy is a software architecture where a single instance of an application serves multiple tenants (customers or users). Each tenant's data is logically isolated, ensuring privacy and security while sharing the same infrastructure. This model is widely used in SaaS platforms like Salesforce, Google Workspace, and Dropbox.
Key Features of Multi-Tenancy
- Shared Infrastructure: Tenants share the same hardware and software resources.
- Tenant Isolation: Data and configurations are isolated for each tenant.
- Cost Efficiency: Shared resources reduce costs compared to single-tenant setups.
- Scalability: Easily accommodates more tenants by leveraging shared resources.
Building a Multi-Tenant Application with Next.js
This guide demonstrates how to build a multi-tenant application using Next.js with subdomain-based tenant separation, like tenant1.yourdomain.com
, tenant2.yourdomain.com
, etc.
🧪 Live Demo · View Source Code
Folder Structure
Organize your project like so:
1├── app/
2│ ├── [subdomain]/ # Tenant-specific routes
3│ │ ├── page.tsx # Main page for the tenant
4│ │ └── layout.tsx # Layout wrapper for each tenant
5│ └── middleware.ts # Middleware for subdomain handling
6├── public/
7│ └── images/tenant1/ # Static assets per tenant
8├── package.json # Project config
9├── .env # Environment variables
Creating Middleware for Subdomain Routing
The middleware identifies tenants from the subdomain, handles auth, and rewrites routes dynamically.
1import { NextResponse } from "next/server";
2import type { NextRequest } from "next/server";
3import { domain } from "@/lib/env";
4
5export function middleware(request: NextRequest) {
6 const hostname = request.headers.get("host") || "";
7 const url = request.nextUrl.clone();
8 const tenantSlug = hostname.split(".")[0];
9
10 if (hostname === domain || hostname === domain.split(":")[0]) {
11 return NextResponse.redirect(new URL(`http://login.${domain}`));
12 }
13
14 if (tenantSlug === "login") {
15 if (url.pathname !== "/" && url.pathname !== "/api/login") {
16 return NextResponse.redirect(new URL("/", request.url));
17 }
18 return NextResponse.next();
19 }
20
21 const userId = request.cookies.get("userId")?.value;
22 if (!userId && tenantSlug !== "login") {
23 return NextResponse.redirect(new URL(`http://login.${domain}/`, request.url));
24 }
25
26 url.pathname = `/${tenantSlug}${url.pathname}`;
27 return NextResponse.rewrite(url);
28}
29
30export const config = {
31 matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
32};
How the Middleware Works
- Subdomain Detection: Extracts the subdomain from the
Host
header. - Authentication: Redirects unauthenticated users to
login.yourdomain.com
. - Route Rewriting: Rewrites the request to target
app/[subdomain]/
. - Cookie Management: Uses a cookie (
userId
) for simple auth handling.
Implementation Steps
1. Configure Domains
Point both your root domain and subdomains to the same server.
2. Environment Variables
Define your domain in .env
:
1DOMAIN=yourdomain.com
3. Local Development
Use local DNS mapping (e.g., /etc/hosts
) to simulate subdomains:
1127.0.0.1 login.localhost tenant1.localhost tenant2.localhost
4. Authentication Flow
Create a login page on the login subdomain. Upon successful login, set a userId
cookie.
⚠️ Note: In practice, JWTs or secure cookies should be used. Since cross-domain cookies can be problematic, you may pass tokens via query params as a fallback.
5. Tenant-Specific Pages
Build tenant-specific components inside the app/[subdomain]/
directory.
Why Use This Pattern?
- Scalability: Add new tenants simply by adding folders.
- Isolation: Subdomain routing provides clean namespace separation.
- Flexibility: Middleware allows fine-grained control over auth and routing logic.
Limitations & Caveats
🧠 This approach is based on a personal project and is not a full production-ready solution.
For robust cross-subdomain authentication and domain aliasing, consult more comprehensive guides or frameworks tailored for SaaS.
Reference
- How to Build a Multi-Tenant App with Custom Domains Using Next.js
- Next.js Middleware Documentation
- My GitHub
Have feedback or want to contribute? Reach out on GitHub or share this post with someone building a SaaS product.