Local Development
Each Booki app runs on a separate port. One app requires a subdomain in the local URL to simulate the multi-tenant pattern used in production.
Quick Reference
| App | Local URL Pattern | Example |
|---|---|---|
cms-booki-web-app | http://localhost:3000/ | http://localhost:3000/ |
owner-booki-web-app | http://localhost:3001/ | http://localhost:3001/ |
customer-booki-web-app | http://{slug}.localhost:3002/{branchSlug} | http://janesbeautysalon.localhost:3002/pampanga |
admin-booki-web-app | http://localhost:3003/ | http://localhost:3003/ |
CMS, Owner & Admin Apps
These apps have no tenant context in the URL. Access them directly on their port — no subdomain required.
http://localhost:3000/ # cms-booki-web-app
http://localhost:3001/ # owner-booki-web-app
http://localhost:3003/ # admin-booki-web-app
Owner App
The owner app runs directly on its port — no subdomain required. The organization context is derived entirely from the authenticated user's JWT (req.user.organizationId) after login.
http://localhost:3001/
Customer App — Subdomain + Branch Slug
The customer app requires both a subdomain (organization slug) and a URL path segment (branch slug).
http://{slug}.localhost:3002/{branchSlug}
# Example
http://janesbeautysalon.localhost:3002/pampanga
What each part does:
| Part | Example | Injected as |
|---|---|---|
| Subdomain | janesbeautysalon | x-tenant-slug header |
| Path segment | /pampanga | x-branch-slug header |
The branch slug comes from the [branchSlug] dynamic route parameter. A client plugin syncs it to state on every navigation and injects it into all API requests via a $fetch interceptor.
Default branch redirect
Visiting http://{slug}.localhost:3002/ (no branch slug) triggers an automatic redirect. The app calls GET /api/v1/tenant/{slug}/default-branch and navigates to /{defaultBranchSlug}.
*.localhost Subdomain Support
Chrome and Edge resolve *.localhost natively — no /etc/hosts changes are needed. Just start the app and open the subdomain URL directly.
Firefox does not resolve *.localhost by default. Enable it in about:config:
- Open
about:configand accept the warning. - Search for
network.dns.localDomains. - Set its value to
localhost. - Restart Firefox.
BASE_DOMAIN for Local Development
When running locally, set BASE_DOMAIN=.localhost in each app's .env so that auth cookies are scoped correctly across *.localhost subdomains. Using .booki.app locally will prevent cookies set on janesbeautysalon.localhost from being sent to other subdomains.
# Local development
BASE_DOMAIN=.localhost
# Production
BASE_DOMAIN=.booki.app
Related
- Multi-Tenancy & Tenant Slug Resolution — how the API resolves slugs to organization IDs
- Installation — full setup instructions and environment variable reference
