How to Implement Multi-Tenancy in Next.js: A Complete Guide
Multi-tenancy is a common architectural pattern in SaaS applications, enabling multiple tenants (customers, businesses, or users) to share a single instance of an application while keeping their data isolated. Implementing multi-tenancy in Next.js requires careful planning around routing, database architecture, security, and deployment.
In this guide, we’ll explore the best practices for setting up a multi-tenant Next.js application, highlight common pitfalls, and provide practical solutions based on real-world use cases.
1. Understanding Multi-Tenancy in Next.js
What is Multi-Tenancy?
Multi-tenancy allows multiple users or organizations to access a single application instance while ensuring their data remains isolated. It’s a common need for SaaS platforms, marketplace apps, and white-labeled solutions.
Common Multi-Tenancy Approaches in Next.js
There are two primary methods for handling multi-tenancy in a Next.js application:
- Subdomain-based Tenancy (tenant1.myapp.com, tenant2.myapp.com)
- Each tenant has a unique subdomain.
- Requires wildcard domain setup.
- Suitable for branding and isolated environments.
- Path-based Tenancy (myapp.com/tenant1, myapp.com/tenant2)
- Uses dynamic routing to differentiate tenants.
- Easier to manage without custom DNS configuration.
- Preferred when SEO and domain authority consolidation matter.
Choosing Between Subdomains and Paths
- If you need custom branding per tenant → Use subdomains.
- If you want better SEO and simpler infrastructure → Use path-based routing.
2. Setting Up Multi-Tenancy in Next.js
Extracting the Tenant from the Request
To serve different tenants dynamically, we need to extract the tenant identifier from either the subdomain or the URL path. This can be achieved using Next.js middleware.
Middleware for Subdomain-Based Routing
import { NextRequest, NextResponse } from 'next/server';export function middleware(req) {const url = new URL(req.url);const subdomain = url.hostname.split('.')[0]; // Extract subdomainif (subdomain !== 'www' && subdomain !== 'myapp') {req.headers.set('x-tenant', subdomain);}return NextResponse.next();}
This middleware extracts the subdomain and passes it as a custom header to API routes and pages.
Middleware for Path-Based Routing
export function middleware(req) {const pathSegments = req.nextUrl.pathname.split('/');if (pathSegments.length > 1) {const tenantId = pathSegments[1]; // Extract tenant ID from URLreq.headers.set('x-tenant', tenantId);}return NextResponse.next();}
This approach dynamically identifies the tenant based on the first segment of the URL path.
3. Handling Multi-Tenant Data in the Database
Database Architecture: Shared vs. Isolated
One of the biggest decisions in multi-tenancy is how to store tenant data. There are two primary database strategies:
- Shared Database with Tenant Identifiers (Recommended for most SaaS platforms)
- A single database where all tenant data exists with a tenant_id field.
- Requires Row-Level Security (RLS) or scoped queries.
- Isolated Database per Tenant
- Each tenant has its own database.
- Harder to manage at scale, but provides stronger data isolation.
Code Example: Enforcing Tenant Isolation in a Shared Database
For PostgreSQL, you can enforce Row-Level Security (RLS):
CREATE POLICY tenant_isolationON usersFOR SELECTUSING (tenant_id = current_setting('app.tenant_id')::UUID);
With Prisma, ensure all queries are scoped:
const db = new PrismaClient();const users = await db.user.findMany({where: { tenantId: tenant_id_from_request },});
If you’re using a separate database per tenant, dynamically switch database connections:
function getTenantDB(tenantId) {return new PrismaClient({datasources: {db: {url: process.env[`DATABASE_URL_${tenantId}`] || process.env.DEFAULT_DATABASE_URL,},},});}
4. Deploying Multi-Tenant Next.js Applications
Handling SSL for Dynamic Subdomains
For subdomain-based multi-tenancy, each subdomain needs an SSL certificate. Using Cloudflare, AWS ACM, or Let’s Encrypt can help automate this.
certbot certonly --manual --preferred-challenges=dns \--email admin@myapp.com --agree-tos \-d *.myapp.com
This command provisions a wildcard SSL certificate for subdomains.
Deploying Multi-Tenant Next.js Apps on Vercel
If deploying to Vercel, use their multi-tenancy starter kit:
- Add a wildcard domain (*.myapp.com).
- Use Next.js middleware to extract the subdomain.
For AWS Route 53 + CloudFront, configure wildcard subdomain routing:
- Set up CNAME records for subdomains.
- Use Lambda@Edge for request rewriting.
5. Authentication & Security in Multi-Tenant Next.js
Role-Based Access Control (RBAC)
Each tenant should have user roles with restricted permissions.
Example of an RBAC check in an API route:
export default async function handler(req, res) {const tenantId = req.headers['x-tenant']; // Extract tenant from middlewareif (!tenantId) {return res.status(403).json({ error: 'Unauthorized' });}const data = await getTenantDB(tenantId).user.findMany();res.status(200).json(data);}
Cross-Tenant Data Protection
- Use Row-Level Security (RLS) in databases.
- Store tenant information in JWT tokens.
- Ensure API requests always include tenant verification.
6. Local Development for Multi-Tenancy
Testing Subdomains Locally
For subdomain-based development:
- Edit your /etc/hosts file:
127.0.0.1 tenant1.localhost127.0.0.1 tenant2.localhost
- Use a local proxy like Caddy or nginx.
For path-based routing, run:
localhost:3000/tenant1
7. Key Takeaways & Final Thoughts
- Subdomains vs. Path-based Routing: Choose based on branding, SEO, and complexity.
- Database Management: Shared databases with tenant IDs and RLS offer a good balance of security and maintainability.
- Next.js Middleware: Extract tenant identifiers dynamically for flexible multi-tenancy.
- Deployment: Handle wildcard SSL and domain mapping efficiently with Cloudflare or AWS.
- Security Best Practices: Enforce RBAC, isolate tenant data, and validate every request.
If you’re building a multi-tenant SaaS, getting authentication and payments right can be a challenge. Update simplifies authentication and billing for multi-tenant applications, reducing development overhead while ensuring scalability.
8. Simplify Multi-Tenancy with Update
Implementing multi-tenancy in Next.js can get complex fast—managing dynamic subdomains, enforcing security, handling authentication, and ensuring data isolation all require significant effort. If you don’t want to deal with the complexities of multi-tenancy yourself, Update makes it easy.
With Update, you can:
- Automate Multi-Tenant Authentication – Handle subdomain or path-based user authentication effortlessly.
- Manage Tenant Billing – Seamlessly integrate tenant-based billing models without custom logic.
- Ensure Secure Data Isolation – Keep tenant data secure without worrying about implementing Row-Level Security yourself.
- Deploy with Zero Hassle – No need to configure wildcard domains or manually manage SSL certificates.
Instead of spending weeks setting up your own multi-tenant infrastructure, Update gives you a plug-and-play solution that scales with your business.
Want to see how it works? Try Update today and focus on building your product instead of managing infrastructure.