In-depth Next.js guides covering App Router, RSC, ISR, and deployment. Get code examples, optimization checklists, and prompts to accelerate development.
This guide focuses on implementing a high-performance, hardcoded multi-tenant architecture with minimal overhead for predetermined tenants. Perfect for enterprise applications with a fixed number of tenants.
Overview
The architecture combines Next.js middleware-based routing with Payload CMS's multi-tenant plugin to achieve complete data isolation while maintaining optimal performance through hardcoded tenant configuration.
exportdefaultasyncfunctionTenantLayout({
children,
params,
}: {
children: React.ReactNode;
params: Promise<{ tenant: string }>;
}) {
const { tenant } = await params;
// Fetch tenant-specific dataconst [navbar, footer, businessInfo] = awaitPromise.all([
## 3.PayloadConfiguration (payload.config.ts)
Configure the multi-tenant plugin to enforce data isolation.
> **Related:** For a deep dive on handling tenant-specific globals (like navbars and footers), see [How to ConfigureGlobalswithMulti-TenantPlugin](/blog/how-to-configure-globals-with-multi-tenant-plugin-in-payload-cms).
```typescript
// ... existing config ...
code
getFooter(tenant),
getBusinessInfo(),
]);
return (
{children}
);
}
code
### Metadata Generation
**For SEO metadata generation** across routes with tenant-specific titles, descriptions, and image URLs, see [Multi-Tenant SEO with Payload & Next.js — Complete Guide](/blog/multi-tenant-seo-payload-nextjs-guide).
## 5. Production Deployment Considerations
### Environment Variables:
```bash
# Database
## 4. Middleware & Frontend Route Structure
> **Advanced Routing:** If you need to serve multiple collections (e.g., Pages and Posts) from the same route root, check out [Multiple Collections on One Route](/blog/payload-cms-multiple-collections-one-route).
The frontend needs to know which tenant is active to fetch the correct data.
# Payload
PAYLOAD_SECRET=your-secret-key
# Tenant domains (optional, for validation)
ALLOWED_TENANT_DOMAINS=tenant1.yourdomain.com,tenant2.yourdomain.com
Vercel Configuration (vercel.json):
json
{"framework":"nextjs","regions":["iad1"],// Single region for consistency"functions":{"src/middleware.ts":{"runtime":"edge"}}}
// In middlewareconsole.log(`[Tenant Routing] ${hostname} -> ${tenant?.slug || 'not-found'}`);
// In page handlersconsole.log(`[Page Request] Tenant: ${tenant}, Path: ${pathname}`);
// In database queriesconsole.log(`[DB Query] Fetching page for tenant: ${tenant}, slug: ${slug}`);
Performance Metrics:
Track middleware execution time
Monitor cache hit rates per tenant
Measure database query performance with tenant filters
Summary
This production-ready multi-tenant setup provides:
Maximum Performance: Hardcoded configuration eliminates runtime lookups
Complete Data Isolation: Payload CMS plugin ensures database-level separation
Clean URLs: Domain-based routing with middleware
Type Safety: Full TypeScript support
Development Efficiency: Local domain mapping for realistic testing
Scalability: Easy to add new tenants without code changes
The approach is ideal for enterprise applications with a predetermined number of tenants, offering the best balance of performance, security, and maintainability.