Configuration
AI Web Launcher centralizes brand identity in one file (config.ts) and theme tokens in one place (app/globals.css). Everything else is optional environment variables.
config.ts
config.ts is the single source of truth for your brand. Edit these tokens first:
const config = {
// REQUIRED
appName: "AI Web Launcher",
appDescription: "A zero-config Next.js boilerplate for AI-powered websites.",
// naked domain — no https://, no trailing slash
domainName: "your-domain.com",
crisp: { id: "", onlyShowOnRoutes: ["/"] },
googleAnalytics: { measurementId: "", streamId: "" },
stripe: { plans: [ /* your plans */ ] },
resend: {
fromNoReply: `AI Web Launcher <noreply@your-domain.com>`,
fromAdmin: `AI Web Launcher <hello@your-domain.com>`,
supportEmail: "hello@your-domain.com",
},
colors: {
theme: "light", // default mode (light | dark) — tokens in app/globals.css
main: "#1F6F73", // browser tab / loading-bar color (keep in sync with --color-primary)
},
auth: { loginUrl: "/signin", callbackUrl: "/dashboard" },
};appName, appDescription, and domainName re-brands the SEO tags, OG images, sitemap, and structured data across the whole site.Theme & palette
Color tokens live in app/globals.css inside the @theme block and the [data-theme="light"] / .dark blocks. They are shadcn/ui OKLCH variables:
:root {
/* REPLACEABLE starter palette — Signal Violet + Circuit Cyan */
--primary: oklch(0.542 0.179 288); /* violet — CTAs, focus rings */
--primary-foreground: oklch(0.985 0 0);
--accent: oklch(0.750 0.120 218); /* cyan — accent partner */
--ring: oklch(0.542 0.179 288);
--background: oklch(1 0 0); /* page background */
--foreground: oklch(0.18 0.006 285); /* body text */
--secondary: oklch(0.967 0.001 286); /* cards, surfaces */
--border: oklch(0.92 0.004 286); /* hairlines */
}To re-skin the whole site, change these values. The [data-theme="light"] and .dark blocks override per theme. Keep config.colors.main in sync with --color-primary so the browser chrome matches.
/docs route has its own token set (--docs-*) further down in globals.css. Adjust --docs-primary to match your brand if you want docs to share the site palette.Environment variables
All integrations are optional and env-gated — the app boots without any of them. Copy .env.example to .env.local and fill in only what you need:
$cp.env.example .env.local| Variable | Purpose | Required? |
|---|---|---|
| NEXT_PUBLIC_SUPABASE_URL | Supabase project URL | Only for auth / leads |
| NEXT_PUBLIC_SUPABASE_ANON_KEY | Supabase anon key | Only for auth / leads |
| SUPABASE_SERVICE_ROLE_KEY | Server-side Supabase writes | Only for lead capture |
| RESEND_API_KEY | Transactional email | Only for email |
| NEXT_PUBLIC_CRISP_ID | Crisp chat website ID | Only for chat |
| NEXT_PUBLIC_GA_ID | Google Analytics 4 ID | Only for analytics |
| STRIPE_SECRET_KEY | Stripe payments | Only for checkout |
| NEXT_PUBLIC_DOMAIN | Naked domain for www→apex redirect | Optional |
When a key is absent, the related feature is silently disabled (no crash). See Best practices for the fail-soft pattern.