A production-ready Next.js application demonstrating multi-tenancy with subdomains and custom domains, deployed on Cloudflare Workers.
- ✅ Subdomain routing: Each tenant gets
tenant.yourdomain.com - ✅ Custom domains: Users can add
example.compointing to their content - ✅ Automatic SSL: Certificates provisioned via Cloudflare for SaaS
- ✅ Global edge: Deployed on Cloudflare Workers for worldwide performance
- ✅ Tenant-specific content and pages
- ✅ Shared components and layouts across tenants
- ✅ Redis for tenant data storage
- ✅ Admin interface for managing tenants
- ✅ Emoji support for tenant branding
- ✅ Support for local development with subdomains
- ✅ Compatible with Cloudflare Workers preview deployments
- ✅ DNS configuration instructions for custom domains
- Next.js 15 with App Router
- React 19
- Cloudflare Workers for hosting
- OpenNext for Next.js compatibility
- Upstash Redis for data storage
- Cloudflare for SaaS for custom domains
- Tailwind 4 for styling
- shadcn/ui for the design system
The detailed guide covers:
- Architecture overview with diagrams
- Step-by-step Cloudflare configuration
- Custom domain DNS setup (CNAME, TXT, DCV delegation)
- Complete code examples and troubleshooting
- Node.js 18.17.0 or later
- pnpm (recommended) or npm/yarn
- Cloudflare account with Workers enabled
- Upstash Redis account (for production)
git clone https://github.com/florianheysen/platforms-cf-worker.git
cd platforms-cf-worker
pnpm installCreate .env.local:
# Cloudflare API
CLOUDFLARE_API_TOKEN=your_api_token
CLOUDFLARE_ZONE_ID=your_zone_id
CLOUDFLARE_ACCOUNT_ID=your_account_id
# Root domain
ROOT_DOMAIN=yourdomain.com
PROTOCOL=https
# Redis (Upstash)
UPSTASH_REDIS_REST_URL=your_redis_url
UPSTASH_REDIS_REST_TOKEN=your_redis_tokenpnpm devAccess:
- Main site:
http://localhost:3000 - Admin panel:
http://localhost:3000/admin - Test tenant:
http://test.localhost:3000
pnpm deployUser Request → Cloudflare Edge → Next.js Middleware → Tenant Detection → Content
Key Components:
- Next.js 15 with App Router
- OpenNext for Cloudflare Workers compatibility
- Cloudflare for SaaS for custom domains & SSL
- Upstash Redis for tenant data
- Tailwind CSS for styling
- ✅ Subdomain routing (
tenant.yourdomain.com) - ✅ Custom domains (
example.com) with automatic SSL - ✅ Admin interface for tenant management
- ✅ Redis-based data storage
- ✅ Global edge deployment
- ✅ Local development support
- Complete Tutorial - Detailed guide with diagrams
- Cloudflare for SaaS - Official documentation
- OpenNext - Next.js → Workers adapter
- Upstash Redis - Serverless Redis
This application is designed to be deployed on Cloudflare Workers using OpenNext. To deploy:
- Push your repository to GitHub
- Configure Cloudflare Workers and Cloudflare for SaaS
- Set up environment variables in Cloudflare Workers
- Deploy using
wrangler deploy
-
Add your domain to Cloudflare:
- Add your root domain to Cloudflare
- Set up wildcard DNS record (
*.yourdomain.com) pointing to your Workers app
-
Enable Cloudflare for SaaS:
- Go to SSL/TLS → Custom Hostnames
- Enable Custom Hostnames
- Configure fallback origin to your Workers app
-
Deploy the application:
pnpm deploy
-
Configure custom domains:
- Users can add custom domains through the settings page
- Custom domains are automatically added to Cloudflare for SaaS
- Users configure CNAME records pointing to your Cloudflare domain
- Navigate to
[subdomain].yourdomain.com/settings - Enter the custom domain (e.g.,
example.com) - The domain will be automatically added to Cloudflare for SaaS
- Configure DNS with the provided CNAME record pointing to your Cloudflare domain
- Verify domain ownership (may require TXT record or nameserver change)
- SSL certificate will be automatically generated by Cloudflare
- The custom domain will route to the same content as the subdomain
To enable custom domain functionality, you need to set up Cloudflare API access:
- CLOUDFLARE_API_TOKEN: Your Cloudflare API token with Custom Hostnames permissions
- CLOUDFLARE_ZONE_ID: Your Cloudflare zone ID (found in domain dashboard)
- CLOUDFLARE_ACCOUNT_ID: Your Cloudflare account ID (found in domain dashboard)
- ROOT_DOMAIN: Your root domain (e.g.,
yourdomain.com) - PROTOCOL: Protocol to use (
https)
When users add custom domains, Cloudflare may require domain verification:
- TXT Record: Add a TXT record to your DNS settings
- Nameservers: Switch to Cloudflare's nameservers (provided in Cloudflare dashboard)
Feel free to open issues and pull requests for improvements!
MIT License - see LICENSE file for details.