Configure Tenants
Tenants are sites identified by domain. Each tenant has its own name, theme, logo, and SEO settings. The frontend shows the tenant whose domain matches the request host.
Create a tenant
- Open the Admin panel (e.g.
http://localhost:3000/admin). - Go to Tenants in the sidebar and click Create New.
- Set:
- Name — internal label (e.g. “Acme Corp”). Used in the admin only.
- Domain — the host visitors use (e.g.
localhost:3000for local dev, ormysite.comin production). Must be unique.
- Optionally configure:
- Site name — public-facing name shown in the header and metadata.
- Theme — pick from 22+ built-in color themes (see Extras → Theming).
- Site logo — square logo upload used in the header.
- Metadata — default title, description, favicon, and OG image for SEO.
- Header / Footer / Banner — layout and navigation for the tenant’s frontend.
- Legal — terms, privacy, and license pages (rich text).
- Save.
After saving, requests to that domain will resolve to this tenant and show its frontend.
How routing works
The app matches the request host to the tenant’s domain field and serves that tenant’s frontend. Paths under /admin, /api, and /docs are shared and not tenant-scoped.
Local development with one tenant
The simplest setup: create a tenant with domain localhost:3000 and visit http://localhost:3000.
- Frontend —
http://localhost:3000(tenant site) - Admin —
http://localhost:3000/admin - Docs —
http://localhost:3000/docs
This is all you need if you’re working with a single site.
Local development with multiple tenants
To test multiple tenants locally, you need each tenant to have a different hostname. Since they all run on the same localhost:3000 server, use your system’s hosts file to create aliases.
Step 1 — Edit /etc/hosts
macOS / Linux:
sudo nano /etc/hostsAdd lines mapping your desired hostnames to 127.0.0.1:
127.0.0.1 tenant1.local
127.0.0.1 tenant2.localSave and exit (Ctrl+O, Enter, Ctrl+X in nano).
Windows (PowerShell as admin):
notepad C:\Windows\System32\drivers\etc\hostsAdd the same lines and save.
Step 2 — Flush DNS cache (if needed)
Most systems pick up the change immediately. If your browser doesn’t resolve the new hostname:
# macOS
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
# Linux (systemd-resolved)
sudo systemd-resolve --flush-cachesStep 3 — Create tenants in the admin
- Go to
http://localhost:3000/admin→ Tenants → Create New. - Create Tenant A with domain
tenant1.local:3000. - Create Tenant B with domain
tenant2.local:3000.
Step 4 — Visit each tenant
http://tenant1.local:3000→ shows Tenant A’s sitehttp://tenant2.local:3000→ shows Tenant B’s sitehttp://tenant1.local:3000/admin→ admin panel (same on any host)
Each tenant has its own pages, posts, theme, and SEO — all from the same running app.
Browser caveats
- Use
.localor.testTLDs — Chrome force-redirects.devdomains to HTTPS (via HSTS preload), which breaks local dev without SSL. Stick to.localor.test. - Cookies are domain-scoped — signing in on
tenant1.localdoes not carry the session totenant2.local. This is expected; each tenant domain has its own cookies. - Port is part of the domain — the tenant domain must include the port for local dev (e.g.
tenant1.local:3000, not justtenant1.local).
Production
Set the tenant’s domain to the real host (e.g. mysite.com). Ensure DNS for that host points to your app (see Deployment for Railway and Vercel specifics). The app matches the request host to the tenant’s domain field; no path prefix is needed.
For multiple production tenants, each domain must have DNS pointing to your hosting provider, and (on Vercel) each domain must be added as a custom domain in the project settings.
Revalidation
When you create or update a tenant, the app revalidates the relevant frontend routes so changes (e.g. site name, theme) appear without a manual redeploy.