Configuration
Brand identity, tenancy mode, routing, and feature flags — every knob in one place.
This template is designed so that a buyer touches as few files as possible to ship a white-labelled product. This page covers every configuration surface.
Brand identity
File: src/config/brand.ts
This is the single source of truth for your product identity. Edit it once and everything propagates — marketing pages, auth screens, email templates, legal docs.
export const brand = {
name: "My Product",
legalEntity: "My Product, Inc.",
tagline: "Do the thing, faster.",
description: "One-line description for SEO and email footers.",
supportEmail: "support@myproduct.com",
url: "https://myproduct.com",
// ...
};
Assets
Drop your logo files into public/brand/:
| Filename | Usage |
|----------|-------|
| logo-light.svg | Light mode header |
| logo-dark.svg | Dark mode header |
| icon.svg | Favicon (32×32) |
| og.png | Open Graph image (1200×630) |
Theme
The theme block in brand.ts sets OKLCH color values injected into globals.css:
theme: {
primary: "oklch(0.6 0.2 250)", // brand primary
accent: "oklch(0.65 0.18 200)", // accent / highlight
radius: "0.5rem", // border-radius base
preset: "default", // "default" | "brutalist" | "soft-pop" | "tangerine"
font: "geist", // "geist" | "inter" | "cal-sans" | ...
},
Tenancy mode
Env var: TENANCY_MODE
| Value | URL pattern | Notes |
|-------|-------------|-------|
| cookie (default) | app.com/dashboard | Active org stored in cookie; simplest to deploy |
| path | app.com/acme/dashboard | Org slug is the first path segment |
| subdomain | acme.app.com/dashboard | Requires wildcard DNS + Vercel wildcard domain |
The proxy (src/proxy.ts) and tenancy resolver (src/lib/tenancy/) handle all three modes behind the same interface. Business logic never branches on TENANCY_MODE.
Host routing
Env var: ROOT_DOMAIN
In subdomain tenancy mode, ROOT_DOMAIN separates the apex (marketing) host from the app host:
ROOT_DOMAIN=myproduct.com
Apex host: myproduct.com → marketing pages
App host: app.myproduct.com → dashboard
Tenant hosts: acme.myproduct.com → tenant dashboard (subdomain mode)
In cookie and path modes ROOT_DOMAIN is still read by the proxy but the apex/app split collapses — both are served on the same domain.
How marketing rewrites work
The proxy rewrites requests on the apex host to the /marketing route group:
myproduct.com/→src/app/marketing/page.tsxmyproduct.com/pricing→src/app/marketing/pricing/page.tsxmyproduct.com/blog→src/app/marketing/blog/page.tsx
/docs is a top-level route (not inside /marketing) so it is served directly without a rewrite. It is accessible on both hosts.
Important:
/docsand/blogmust be listed inPUBLIC_PREFIXESinsidesrc/proxy.tsto bypass the auth gate. Without this, unauthenticated visitors on the app host will be redirected to/login. See the note at the bottom of this page.
Feature flags
Feature flags live in src/config/app-config.ts. They are plain TypeScript constants — no external service required.
export const appConfig = {
billing: {
enabled: true, // show pricing page and billing portal
trialDays: 14,
},
invites: {
enabled: true, // org invitation flow
maxPerOrg: 50,
},
auditLog: {
enabled: false, // audit log UI (requires Pro schema)
},
};
Internationalisation
File: src/i18n/request.ts
next-intl is pre-wired. Message files live in messages/. The locale is read from the NEXT_LOCALE cookie and defaults to en. Add a new locale by:
- Adding a message file:
messages/fr.json - Exporting the locale in
src/i18n/routing.ts - Translating keys — the type system will surface missing entries
Email configuration
All email is sent via Resend. Templates are React Email components in src/lib/email/templates/. The from address is read from EMAIL_FROM. To preview templates locally:
pnpm email:dev # starts React Email devserver on :3001
Deployment
The starter is optimised for Vercel:
- Import the repo in the Vercel dashboard
- Set all environment variables from
.env.local - Add
ROOT_DOMAINto your production env - Connect the Neon database integration for automatic
DATABASE_URLinjection
For self-hosting, build with pnpm build and start with pnpm start. Ensure NODE_ENV=production is set so removeConsole and other build-time optimisations activate.
Proxy note: If you add new public-facing routes (like
/docs), remember to add their path prefixes toPUBLIC_PREFIXESinsrc/proxy.ts. Otherwise the edge auth gate will redirect unauthenticated users to/loginbefore your page renders.