Configuration
Customize your SaaS by editing config files — branding, features, pricing, navigation, and more.
All configuration lives in lib/config/. Each file exports a typed object that controls a different aspect of the application. No environment variables are needed for basic customization — just edit the files directly.
site.ts — Brand and Design
The main configuration file. Controls your app name, description, theme, all design options, navigation, hero content, features section, testimonials, FAQ, CTA, announcement bar, and footer.
Basic settings
export const siteConfig: SiteConfig = {
name: "YourSaaS",
description: "Your product description",
url: process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000",
theme: "purple", // "teal" | "blue" | "purple" | "orange" | "green" | "rose"
design: { /* see below */ },
// ...
}design — All 14 options
design: {
// Landing page template
landingTemplate: "classic", // "classic" | "saas" | "startup" | "devtool" | "agency"
// Hero layout (classic template only)
heroStyle: "centered", // "centered" | "split" | "video" | "product"
// Header style
headerStyle: "default", // "default" | "centered" | "minimal" | "floating" | "bordered"
// Hero section background
heroBackground: "particles", // "grid" | "dots" | "gradient" | "particles" | "animated-grid" | "light-rays"
// Hero headline style (classic template only)
heroHeadline: "gradient", // "gradient" | "aurora" | "typing" | "word-rotate" | "plain"
// Hero CTA button style
heroCta: "shimmer", // "glow" | "shimmer" | "outline" | "gradient" | "pill"
// Hero screenshot mockup (classic template only)
heroScreenshot: "safari", // "safari" | "browser" | "none"
// Logo cloud below hero (classic template only)
logoCloud: "marquee", // "marquee" | "static" | "none"
// Features section layout (classic template only)
featuresLayout: "bento", // "grid" | "asymmetric" | "bento" | "tabs"
// Popular plan highlight style
pricingPopular: "border-beam", // "border-beam" | "shine" | "neon" | "glow"
// Testimonials section style (classic template only)
testimonials: "marquee", // "marquee" | "carousel" | "grid" | "featured"
// Section scroll reveal animation
sectionReveal: "blur-fade", // "blur-fade" | "fade-up" | "none"
// Bottom CTA section style
ctaStyle: "banner", // "centered" | "split" | "banner" | "card" | "minimal"
// Theme toggle style
themeToggle: "simple", // "animated" | "simple"
}Landing templates:
classic— Most flexible. Uses allheroStyle,heroBackground,featuresLayout, etc. options.saas— Full-featured SaaS page with bento features, marquee testimonials, pricing, and FAQ.startup— Clean, minimal. Badge hero, trusted-by strip, numbered how-it-works, pricing.devtool— Terminal aesthetic. Code tabs, stats bar, monospace fonts, Aurora headline.agency— Portfolio focus. Split hero, showcase grid, featured testimonial pull-quote.
Header styles:
default— Logo left, nav links center, CTA buttons right.centered— Logo center with nav wrapping around it.minimal— Logo left, single CTA + hamburger on all screen sizes.floating— Detached pill floating below the top edge of the page.bordered— Full-width, spacious enterprise header with a bottom border.
Hero backgrounds:
grid— Subtle CSS grid lines fading from center.dots— Dot pattern at low opacity.gradient— Layered gradient blurs using primary/chart colors.particles— Animated floating particles (uses Magic UIParticles).animated-grid— Moving grid squares (uses Magic UIAnimatedGridPattern).light-rays— Radial light rays effect (uses Magic UILightRays).
Hero CTA styles:
glow— Button with a primary-color glow/shadow effect (default).shimmer— Magic UI ShimmerButton with animated shimmer.outline— Bordered outline that fills with primary color on hover.gradient— Gradient background button with drop shadow.pill— Pill-shaped with a circular arrow indicator.
Theme toggle:
simple— Sun/Moon icon toggle (instant switch).animated— Smooth circular reveal using the View Transitions API (AnimatedThemeToggler).
Hero section
hero: {
badge: "Now in public beta — Try it free",
headline: "Build and ship your product",
headlineHighlight: "10x faster", // styled differently (gradient, aurora, etc.)
headlineWords: ["faster", "smarter", "better"], // used by word-rotate headline
subtitle: "Your subtitle text...",
primaryCta: { label: "Start Building Free", href: "/signup" },
secondaryCta: { label: "See How It Works", href: "#how-it-works" },
socialProof: [
{ value: 2400, label: "developers" },
{ value: 150, label: "components" },
{ value: 99, label: "% uptime" },
],
}Other sections
features: {
headline: "Everything you need, nothing you don't",
subtitle: "...",
items: [
{ icon: Shield, title: "Auth & RBAC", description: "...", className: "col-span-2" },
// className "col-span-2" spans two columns in bento layout
],
},
howItWorks: {
headline: "Up and running in 3 steps",
subtitle: "...",
steps: [{ title: "Clone & Configure", description: "..." }],
},
testimonials: {
headline: "Trusted by builders worldwide",
subtitle: "...",
items: [{ name: "Sarah Chen", role: "Founder, DataFlow", content: "..." }],
},
faq: {
headline: "Frequently asked questions",
subtitle: "...",
items: [{ question: "...", answer: "..." }],
},
cta: {
headline: "Ready to ship your next big idea?",
subtitle: "...",
},
announcement: {
enabled: true,
text: "We just launched v1.2 with team management!",
link: { label: "See what's new →", href: "/changelog" },
},
footer: {
columns: [{ title: "Product", links: [{ label: "Features", href: "#features" }] }],
copyright: "© 2025 YourSaaS. All rights reserved.",
socials: [{ label: "Twitter", href: "#", icon: "twitter" }],
},navLinks
The top navigation links (site header). Feature-flagged links (blog, docs, contact, changelog) are filtered out automatically when their flag is false.
navLinks: [
{ label: "Features", href: "#features" },
{ label: "Pricing", href: "/pricing" },
{ label: "Blog", href: "/blog" },
{ label: "Docs", href: "/docs" },
]features.ts — Feature Flags
Toggle entire features on/off using environment variables. All default to true unless explicitly disabled.
// lib/config/features.ts
export const features = {
blog: process.env.NEXT_PUBLIC_ENABLE_BLOG !== "false",
docs: process.env.NEXT_PUBLIC_ENABLE_DOCS !== "false",
contact: process.env.NEXT_PUBLIC_ENABLE_CONTACT !== "false",
newsletter: process.env.NEXT_PUBLIC_ENABLE_NEWSLETTER !== "false",
organizations: process.env.NEXT_PUBLIC_ENABLE_ORGANIZATIONS !== "false",
waitlist: process.env.NEXT_PUBLIC_ENABLE_WAITLIST !== "false",
feedback: process.env.NEXT_PUBLIC_ENABLE_FEEDBACK !== "false",
changelog: process.env.NEXT_PUBLIC_ENABLE_CHANGELOG !== "false",
search: process.env.NEXT_PUBLIC_ENABLE_SEARCH !== "false",
comingSoon: process.env.NEXT_PUBLIC_COMING_SOON === "true",
demoMode: process.env.NEXT_PUBLIC_DEMO_MODE === "true",
}What each flag controls:
| Flag | Controls |
|---|---|
blog | /blog page + nav link |
docs | /docs pages + nav link |
contact | /contact page + nav link |
newsletter | NewsletterSection on all landing pages |
organizations | Organization tab in dashboard, org switcher |
waitlist | WaitlistSection on all landing pages |
feedback | FeedbackWidget floating button (all pages) |
changelog | /changelog page (returns 404 when false) |
search | CommandPalette (Cmd+K) + search buttons in dashboard |
comingSoon | Redirects all routes to a coming soon page |
demoMode | Enables demo data / restricted interactions |
To disable a feature, add to your .env.local:
NEXT_PUBLIC_ENABLE_NEWSLETTER=false
NEXT_PUBLIC_ENABLE_WAITLIST=falseNEXT_PUBLIC_ variables — they are inlined at build time and work in both server and client components.pricing.ts — Plans and Billing
Defines the four pricing tiers with prices and provider-specific IDs for all three payment providers.
// lib/config/pricing.ts
export const pricingPlans: PlanConfig[] = [
{
id: "FREE",
name: "Free",
description: "For side projects and testing",
price: { monthly: 0, annual: 0 },
features: ["Up to 100 users", "Basic analytics", "Community support"],
lemonsqueezy: { monthlyVariantId: "", annualVariantId: "" },
polar: { monthlyProductId: "", annualProductId: "" },
stripe: { monthlyPriceId: "", annualPriceId: "" },
},
{
id: "PRO",
name: "Pro",
description: "For growing businesses",
price: { monthly: 29, annual: 24 },
popular: true, // highlights this plan with pricingPopular style
features: ["Unlimited users", "Real-time analytics", "API access"],
lemonsqueezy: { monthlyVariantId: "123456", annualVariantId: "123457" },
polar: { monthlyProductId: "uuid-here", annualProductId: "uuid-here" },
stripe: { monthlyPriceId: "price_xxx", annualPriceId: "price_yyy" },
},
]ID types by provider:
| Provider | ID type | Where to find |
|---|---|---|
| LemonSqueezy | Numeric Variant ID | Products → click product → Variants tab |
| Polar | UUID Product ID | Polar Dashboard → Products |
| Stripe | price_xxx Price ID | Stripe Dashboard → Products → click product → Pricing section |
price_xxx) — never Product IDs (prod_xxx). The Price ID is found inside the product, not on the products list.Helper functions:
import { getCheckoutId, getPlanByCheckoutId } from "@/lib/config/pricing"
// Get the provider-specific ID for a plan + interval
const id = getCheckoutId("PRO", "monthly") // returns price_xxx / variantId / productId
// Reverse lookup — used in webhook handlers
const plan = getPlanByCheckoutId(checkoutId)navigation.ts — Dashboard Sidebar
Controls the dashboard sidebar with role-based section visibility. Groups with a roles array only appear for users with those roles.
// lib/config/navigation.ts
export const navigationConfig: NavGroup[] = [
{
heading: "Overview",
items: [
{ label: "Dashboard", href: "/dashboard", icon: LayoutDashboard },
],
},
{
heading: "Settings",
items: [
{ label: "Profile", href: "/dashboard/settings", icon: User },
{ label: "Billing", href: "/dashboard/billing", icon: CreditCard },
{ label: "Notifications", href: "/dashboard/settings/notifications", icon: Bell },
],
},
{
heading: "Admin",
items: [{ label: "Admin Panel", href: "/dashboard/admin", icon: Shield }],
roles: ["ADMIN"], // only visible to ADMIN role
},
{
heading: "Platform",
items: [
{ label: "Overview", href: "/dashboard/superadmin", icon: BarChart3 },
{ label: "Users", href: "/dashboard/superadmin/users", icon: Users },
// ...
],
roles: ["SUPERADMIN"], // only visible to SUPERADMIN role
},
]Use getFilteredNav(role) to get role-appropriate navigation in components.
changelog.ts — Version History
Array of entries displayed on the /changelog page (when features.changelog is true).
// lib/config/changelog.ts
export const changelog: ChangelogEntry[] = [
{
type: "feature", // "feature" | "improvement" | "fix"
version: "1.2.0",
date: "2025-03-15",
title: "Team Management & Organizations",
items: ["Multi-tenant organization system with RBAC", "..."],
},
]legal.ts — Terms and Privacy
Template content for /terms and /privacy pages. Replace [Company Name] and [companydomain] placeholders before going live.