SecureStartKit
SecurityFeaturesPricingDocsBlogChangelog
Sign inBuy Now
Getting Started
Installation
Configuration
Deployment

Components

  • Hero
  • Pricing
  • Features

Features

  • Authentication
  • Payments
  • Emails
  • Database
  • Blog
  • Security Headers
  • Claude Code Skills

Recipes

  • Add a Server Action
  • Add a Database Table
  • Add an OAuth Provider
  • Add an Email Template
  • Customize the Auth Flow
  • Add an Admin Metric
  • Enable Bot Protection

Configuration

Central config.ts is the single source of truth. App settings, billing plans, appearance, auth, admin, SEO.

Why one config file

Every customization point that matters lives in config.ts at the project root. App name, billing plans, appearance, auth providers, admin emails, SEO defaults: one file, typed against config.types.ts, no scattered constants to hunt through. Edit this and the rest of the template adapts.

The default config.ts ships with SecureStartKit's actual production values as a worked example. Replace them with your own.

App settings

appName: 'YourSaaS',
appDescription: 'Your one-line SEO description.',
domainName: 'yoursaas.com', // No https://, no trailing slash

domainName is used in canonical URLs, the sitemap, structured data, and email templates. Keep it bare (no protocol, no trailing slash).

Billing plans

billing: {
  provider: 'stripe',
  plans: [
    {
      name: 'Starter',
      description: 'A short value-prop sentence.',
      price: { monthly: 199, yearly: 199 },
      priceAnchor: { monthly: 249, yearly: 249 }, // Optional: shows a crossed-out price
      priceId: {
        monthly: 'price_xxx', // From Stripe Dashboard
        yearly: 'price_xxx',
      },
      features: ['Feature 1', 'Feature 2'],
    },
    {
      name: 'Pro',
      description: '...',
      price: { monthly: 249, yearly: 249 },
      priceId: {
        monthly: 'price_xxx',
        yearly: 'price_xxx',
      },
      isFeatured: true, // Highlights as "Most Popular"
      features: ['Everything in Starter', '...'],
    },
  ],
}

Three properties worth knowing:

  • priceAnchor is optional. Setting it renders a crossed-out anchor price next to the real price, which signals discount framing.
  • isFeatured: true highlights the plan as "Most Popular" on the pricing grid.
  • One-time vs subscription: SecureStartKit defaults to one-time billing (monthly === yearly === one-time price). To switch to subscription mode, change mode: 'payment' to mode: 'subscription' in actions/billing.ts and create recurring prices in Stripe. See Payments for the full switch.

Appearance

appearance: {
  defaultTheme: 'system', // 'light' | 'dark' | 'system'
  allowThemeToggle: true,  // Show the toggle in the header
  primaryColor: '#6366f1', // The brand color
}

primaryColor feeds the Tailwind primary token. Change it and every CTA, link, and accent color across the site updates.

Auth providers

auth: {
  providers: ['email', 'google'],
}

Enabling a provider here is the first step. You also need to configure it in the Supabase dashboard (Authentication > Providers) with your OAuth client credentials. The full walkthrough for adding a new provider is in Recipes: Add an OAuth provider.

Admin panel

admin: {
  enabled: true,
  superAdminEmails: ['you@yourdomain.com'],
}

Only users whose email exactly matches an entry in superAdminEmails can access /admin. The check is enforced server-side in the admin layout, not client-side. The list is in config.ts (not a database table) because admin status is an architectural decision, not a per-user setting.

SEO

seo: {
  defaultTitle: 'YourSaaS, Build faster with security built-in',
  titleTemplate: '%s | YourSaaS',
  description: 'A production-ready Next.js SaaS template.',
  keywords: ['saas', 'template', 'nextjs'],
  ogImage: '/og.png',
  twitterHandle: '@yoursaas',
}

These feed the default <head> metadata. Per-page metadata in App Router generateMetadata() overrides these defaults.

Changelog

changelog: {
  enabled: true,
}

When enabled, a /changelog page renders MDX files from content/changelog/. Each entry uses standard frontmatter (title, date, version, categories). Set enabled: false to hide the changelog route entirely.