Configuration
Nearly everything you need to customize when starting a new project lives insaas.config.ts at the project root.
saas.config.ts
Auth Routes Configuration
| Key | Default | Description |
|---|---|---|
protectedRoutes | ["/dashboard", ...] | Prefixes that require authentication |
publicRouteOverrides | ["/invitations/accept"] | Paths under a protected prefix that are public |
authRoutes | ["/", "/auth/login", ...] | Paths that redirect to dashboard if already authed |
afterLoginRedirect | "/dashboard" | Where to send users after sign-in |
loginPath | "/auth/login" | Where to redirect unauthenticated users |
Adding Sidebar Navigation Items
Import a Lucide icon and add it tosidebar.navItems:
SidebarNav below the default Dashboard link with built-in active state detection (pathname.startsWith(href)). Provide isActiveFn to override the default check.
Environment Variables
Copy.env.local.example to .env.local and fill in these values:
Required
| Variable | Description |
|---|---|
NEXT_PUBLIC_SUPABASE_URL | Supabase project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY | Supabase anon key |
SUPABASE_SERVICE_ROLE_KEY | Supabase service role key (server only) |
NEXT_PUBLIC_APP_URL | Base URL (e.g., https://myapp.com) |
Email (Resend)
| Variable | Description |
|---|---|
RESEND_API_KEY | Resend API key |
RESEND_FROM_EMAIL | Verified sender address |
RESEND_SMTP_PASSWORD | For Supabase SMTP relay (production only) |
Billing (Stripe)
| Variable | Description |
|---|---|
STRIPE_SECRET_KEY | Stripe secret key |
STRIPE_WEBHOOK_SECRET | Webhook signing secret |
Cron
| Variable | Description |
|---|---|
CRON_SECRET | Used to authenticate Vercel cron calls |
Design Tokens
All colors use semantic CSS custom properties defined inapp/globals.css. Never hardcode Tailwind color classes like text-gray-900. Use tokens:
| Token | Use for |
|---|---|
text-foreground | Primary text |
text-muted-foreground | Secondary / hint text |
bg-background | Page background |
bg-card | Card surfaces |
border-border | Borders and dividers |
bg-primary / text-primary | Brand / action color |
text-destructive | Error and destructive states |
Key Layout Tokens
| Token | Value | Use |
|---|---|---|
--header-height | set by layout | Top header offset |
--sidebar-width | set by SidebarProvider | Expanded sidebar width |
--z-header | 20 | Authenticated chrome |
--z-modal | 50 | Modals and dialogs |
PageContainer Sizes
ThePageContainer component wraps page content with a max-width:
| Size | Max Width |
|---|---|
compact | max-w-2xl |
narrow | max-w-4xl |
medium | max-w-5xl |
default | max-w-6xl |
wide | max-w-7xl |
full | no max-width |