A powerful and scalable solution for hosting multiple distinct websites from a single Next.js application, using Firebase Firestore for configuration and content management.
The Multi-Tenant Website Engine enables you to host and serve multiple independent websites ("tenants") from a single Next.js application instance. The system dynamically determines which website to serve based on the domain name of the incoming request, applying tenant-specific configurations, styling, and content.
- Domain-Based Routing: Automatically identify and serve the correct tenant website based on domain name
- Tenant Isolation: Complete data isolation between different tenant websites
- Custom Styling: Apply unique themes and styling to each tenant
- Efficient Caching: Local cache system for domain resolution to minimize database queries
- Scalable Architecture: Designed to handle a growing number of tenant sites with minimal overhead
- Single Codebase: Maintain one codebase to power multiple websites, simplifying deployment and updates
This engine uses a middleware-driven approach to intercept incoming requests, identify the appropriate tenant, and serve the correct content:
Request Flow:
┌─────────────┐ ┌──────────────┐ ┌──────────────┐ ┌───────────────┐
│ Incoming │ │ Domain │ │ Site │ │ Rendered │
│ Request ├────►│ Resolution ├────►│ Context & ├────►│ Page │
│ │ │ Middleware │ │ Theming │ │ │
└─────────────┘ └──────────────┘ └──────────────┘ └───────────────┘
│ ▲
▼ │
┌──────────────┐ ┌──────────────┐
│ Cache │ │ Firestore │
│ │◄───►│ Database │
└──────────────┘ └──────────────┘
- Tenant Resolution Middleware: Identifies tenant from domain and loads configuration
- Site Context Provider: Makes site configuration available throughout the application
- Theme Provider: Applies tenant-specific styling
- Data Access Layer: Ensures tenant data isolation in Firestore
- Caching Layer: Optimizes performance for domain resolution and configurations
- Node.js (v18.x or later)
- npm (v9.x or later)
- Firebase project with Firestore enabled
- Git
-
Clone this repository:
git clone https://github.com/404FoundingFather/multi-site.git cd multi-site -
Install dependencies:
npm install
-
Create a
.env.localfile with your Firebase configuration:FIREBASE_PROJECT_ID=your-project-id FIREBASE_PRIVATE_KEY=your-private-key FIREBASE_CLIENT_EMAIL=your-client-email NEXT_PUBLIC_FIREBASE_API_KEY=your-api-key NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-auth-domain NEXT_PUBLIC_FIREBASE_PROJECT_ID=your-project-id CACHE_TTL=300 -
Start the development server:
npm run dev
-
Create a new site document in your Firestore
sitescollection:{ "tenantId": "site1", "domainName": "example.com", "siteName": "Example Site", "themeId": "default", "status": "active", "config": { "logo": "https://example.com/logo.png", "contactEmail": "contact@example.com" } }
-
Create a theme document in the
themescollection:{ "name": "Default Theme", "styles": { "primaryColor": "#3f51b5", "secondaryColor": "#f50057", "backgroundColor": "#ffffff", "textColor": "#333333", "fontFamily": "'Roboto', sans-serif" } }
-
For local development, you can use the domain mocking feature:
npm run dev:mock-domain -- --domain=example.com
Detailed documentation is available in the documents/ directory:
prd.md- Product Requirements Document with detailed specificationslonger-term-optimizations.md- Technical roadmap for future enhancements
├── components/ - Reusable React components
│ ├── common/ - Shared components across all tenants
│ ├── layouts/ - Layout components that adapt to tenant config
│ └── themes/ - Theme-specific components
├── contexts/ - React context definitions
├── documents/ - Project documentation
├── lib/ - Core functionality
│ ├── cache/ - Caching implementations
│ ├── firebase/ - Firebase/Firestore integration
│ ├── site/ - Site context and configuration
│ └── theme/ - Theming utilities
├── memory-bank/ - Project knowledge base
├── middleware.ts - Tenant resolution middleware
├── pages/ - Next.js pages
├── public/ - Static assets
└── styles/ - Global styles and CSS variables
npm run dev- Start the development servernpm run build- Build the application for productionnpm run start- Start the production servernpm run lint- Run ESLint for code qualitynpm test- Run testsnpm run dev:mock-domain -- --domain=example.com- Run with domain mocking
The Multi-Tenant Website Engine can be deployed to Vercel, Google Cloud Run, or any other hosting service that supports Next.js applications. Additional configuration is required for handling custom domains:
-
Build the application:
npm run build
-
Deploy to your hosting service following their specific instructions.
-
Configure DNS settings for each tenant domain to point to your deployed application.
See documents/longer-term-optimizations.md for the detailed technical roadmap, which includes:
- Edge Middleware Implementation
- Advanced Cache Invalidation Strategies
- Serverless Function Optimization
- Firestore Scalability Enhancements
- Theming System Improvements
- Content Delivery Architecture Optimization
- Security Enhancements
- Testing Infrastructure Improvements
- Monitoring and Observability Enhancements
Contributions to the Multi-Tenant Website Engine are welcome! Please refer to the contribution guidelines for details.
This project is licensed under the MIT License - see the LICENSE file for details.
- The Next.js team for the powerful framework
- Firebase for the flexible database and authentication services
- All contributors to this project