Back to Help Center
Customization

Customization Guide

Customization Guide

This guide covers how to customize your SaaS boilerplate with your own branding, pricing, content, and features.

Quick Customization Checklist

Before launching, customize these key areas:

  • [ ] Site name and description
  • [ ] Logo and favicon
  • [ ] Colors and theme
  • [ ] Pricing plans and features
  • [ ] Landing page content
  • [ ] Email templates
  • [ ] Social links
  • [ ] Legal pages (Privacy, Terms)

1. Site Configuration

All site-wide settings are in /config/site.ts:

// /config/site.ts

export const siteConfig = {
  name: 'Your App Name',           // Change this
  description: 'Your app description for SEO and social sharing.',
  url: process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000',
  ogImage: '/og.png',              // Social share image
  links: {
    twitter: 'https://twitter.com/yourusername',
    github: 'https://github.com/yourusername/your-repo',
    docs: '/docs',
  },
  creator: 'Your Name or Company',
  keywords: [
    'Your',
    'Keywords',
    'Here',
  ],
};

What Each Field Does

| Field | Where It Appears | |-------|-----------------| | name | Browser tab, navbar, emails, footer | | description | SEO meta tags, social shares | | url | Absolute URLs in emails, sitemap | | ogImage | Social media preview image | | links.twitter | Footer, social sharing | | links.github | Footer (remove if not applicable) | | creator | Meta tags | | keywords | SEO meta keywords |


2. Logo and Favicon

Replacing the Logo

The logo appears in the navbar and footer. To replace it:

Option A: Text Logo (Current)

Edit the navbar component to change the text:

// In /components/marketing/navbar.tsx
<Link href="/" className="font-bold text-xl">
  Your App Name  {/* Change this */}
</Link>

Option B: Image Logo

  1. Add your logo to /public/images/logo.svg (or .png)
  2. Update the navbar:
// In /components/marketing/navbar.tsx
import Image from 'next/image';

<Link href="/" className="flex items-center">
  <Image
    src="/images/logo.svg"
    alt="Your App Name"
    width={120}
    height={32}
  />
</Link>

Replacing the Favicon

  1. Generate favicons at realfavicongenerator.net

  2. Replace the files in /app/:

    • favicon.ico
    • apple-icon.png (180x180)
    • icon.png (32x32)
  3. Or update /app/layout.tsx metadata:

export const metadata: Metadata = {
  icons: {
    icon: '/favicon.ico',
    apple: '/apple-icon.png',
  },
};

Replacing the OG Image

The OG (Open Graph) image appears when your site is shared on social media:

  1. Create an image (1200x630 pixels recommended)
  2. Replace /public/og.png
  3. Update the path in siteConfig if you use a different filename

3. Colors and Theme

The boilerplate uses Tailwind CSS with CSS custom properties for theming.

Changing the Primary Color

Edit /app/globals.css:

@layer base {
  :root {
    /* Light mode colors */
    --primary: 222.2 47.4% 11.2%;     /* Primary color HSL */
    --primary-foreground: 210 40% 98%;

    /* Change these values to customize */
    /* Example: Blue primary */
    /* --primary: 221 83% 53%; */

    /* Example: Green primary */
    /* --primary: 142 76% 36%; */

    /* Example: Purple primary */
    /* --primary: 262 83% 58%; */
  }

  .dark {
    /* Dark mode colors */
    --primary: 210 40% 98%;
    --primary-foreground: 222.2 47.4% 11.2%;
  }
}

Quick Color Presets

Copy these values to --primary for different color schemes:

| Color | HSL Value | |-------|-----------| | Blue | 221 83% 53% | | Green | 142 76% 36% | | Purple | 262 83% 58% | | Orange | 24 95% 53% | | Red | 0 84% 60% | | Teal | 174 72% 40% | | Pink | 330 81% 60% |

Changing Fonts

  1. Import your font in /app/layout.tsx:
import { Inter, Poppins } from 'next/font/google';

// Replace Inter with your preferred font
const fontSans = Poppins({
  subsets: ['latin'],
  weight: ['400', '500', '600', '700'],
  variable: '--font-sans',
});
  1. Update Tailwind config if needed in tailwind.config.ts:
theme: {
  extend: {
    fontFamily: {
      sans: ['var(--font-sans)', ...fontFamily.sans],
    },
  },
},

4. Pricing Plans

Customize your pricing tiers in /config/stripe.ts:

export const pricingPlans: PricingPlan[] = [
  {
    id: 'free',
    name: 'Starter',                    // Plan name
    description: 'Perfect for trying out',  // Short description
    features: [                         // Feature list (shown as checkmarks)
      'Up to 3 projects',
      'Basic analytics',
      'Community support',
      '1GB storage',
    ],
    priceMonthly: 0,                    // Monthly price in dollars
    priceYearly: 0,                     // Yearly price in dollars
    priceIdMonthly: stripeConfig.priceIds.free,  // Stripe price ID
    priceIdYearly: stripeConfig.priceIds.free,
    cta: 'Get Started',                 // Button text
  },
  {
    id: 'pro',
    name: 'Professional',
    description: 'For growing businesses',
    features: [
      'Unlimited projects',
      'Advanced analytics',
      'Priority email support',
      '50GB storage',
      'Custom domains',
      'Team collaboration (up to 5)',
      'API access',
    ],
    priceMonthly: 49,                   // Change your pricing
    priceYearly: 470,                   // ~20% discount for yearly
    priceIdMonthly: stripeConfig.priceIds.proMonthly,
    priceIdYearly: stripeConfig.priceIds.proYearly,
    popular: true,                      // Shows "Popular" badge
    cta: 'Start Free Trial',
  },
  {
    id: 'enterprise',
    name: 'Enterprise',
    description: 'For large organizations',
    features: [
      'Everything in Professional',
      'Unlimited storage',
      'Dedicated account manager',
      'Custom integrations',
      'SLA guarantee (99.9%)',
      'Advanced security & SSO',
      'Audit logs',
      'Custom training',
    ],
    priceMonthly: 199,
    priceYearly: 1990,
    priceIdMonthly: stripeConfig.priceIds.enterpriseMonthly,
    priceIdYearly: stripeConfig.priceIds.enterpriseYearly,
    cta: 'Contact Sales',
  },
];

Important: Update Stripe Prices

After changing prices, you must:

  1. Create matching products/prices in Stripe Dashboard
  2. Update .env.local with the new Stripe Price IDs:
NEXT_PUBLIC_STRIPE_PRICE_ID_PRO_MONTHLY=price_xxxxxxxxxxxxx
NEXT_PUBLIC_STRIPE_PRICE_ID_PRO_YEARLY=price_xxxxxxxxxxxxx

See STRIPE.md for detailed instructions.


5. Landing Page Content

Hero Section

Edit /components/marketing/hero.tsx:

<h1 className="text-4xl md:text-6xl font-bold">
  Your Main Headline Here
</h1>
<p className="text-xl text-muted-foreground">
  Your subheadline that explains what you do and why it matters.
</p>

Features Section

Edit /components/marketing/features.tsx:

const features = [
  {
    icon: Zap,                          // Lucide icon
    title: 'Lightning Fast',
    description: 'Your feature description here.',
  },
  {
    icon: Shield,
    title: 'Secure by Default',
    description: 'Another feature description.',
  },
  // Add or modify features...
];

Available icons: Import from lucide-react. Browse all icons at lucide.dev.

Testimonials

Edit /components/marketing/testimonials.tsx:

const testimonials = [
  {
    quote: "This product changed how we work. Highly recommended!",
    author: "Jane Smith",
    title: "CEO at TechCorp",
    avatar: "/images/testimonials/jane.jpg",  // Optional
  },
  // Add more testimonials...
];

FAQ Section

Edit /components/marketing/faq.tsx:

const faqs = [
  {
    question: "How does the free trial work?",
    answer: "Start your 14-day free trial with no credit card required. You'll have access to all Pro features during the trial period.",
  },
  {
    question: "Can I cancel anytime?",
    answer: "Yes, you can cancel your subscription at any time. You'll continue to have access until the end of your billing period.",
  },
  // Add more FAQs...
];

Footer Links

Edit /components/marketing/footer.tsx:

const footerLinks = {
  product: [
    { title: 'Features', href: '/#features' },
    { title: 'Pricing', href: '/pricing' },
    { title: 'Blog', href: '/blog' },
  ],
  company: [
    { title: 'About', href: '/about' },
    { title: 'Contact', href: '/contact' },
    { title: 'Careers', href: '/careers' },
  ],
  legal: [
    { title: 'Privacy', href: '/privacy' },
    { title: 'Terms', href: '/terms' },
  ],
};

6. Navigation

Edit /config/navigation.ts:

// Marketing site navigation
export const mainNav = [
  { title: 'Features', href: '/#features' },
  { title: 'Pricing', href: '/pricing' },
  { title: 'Blog', href: '/blog' },
  { title: 'Docs', href: '/docs' },  // Add or remove links
];

// Dashboard sidebar navigation
export const dashboardNav = [
  { title: 'Dashboard', href: '/dashboard' },
  { title: 'Settings', href: '/dashboard/settings' },
  { title: 'Billing', href: '/dashboard/billing' },
  // Add your app's pages here
];

7. Email Templates

See the dedicated Email Customization Guide for detailed instructions.

Quick overview of email template locations:

| Email | File | When Sent | |-------|------|-----------| | Welcome | /emails/welcome.tsx | After signup | | Subscription Confirmed | /emails/subscription-confirmed.tsx | After payment | | Subscription Canceled | /emails/subscription-canceled.tsx | After cancellation | | Payment Failed | /emails/payment-failed.tsx | Payment failure |


8. Legal Pages

You should create these pages before launching:

Privacy Policy

Create /app/privacy/page.tsx:

export default function PrivacyPage() {
  return (
    <div className="container py-12 max-w-3xl">
      <h1 className="text-3xl font-bold mb-8">Privacy Policy</h1>

      <p className="mb-4">Last updated: January 1, 2025</p>

      <h2 className="text-xl font-semibold mt-8 mb-4">1. Information We Collect</h2>
      <p className="mb-4">
        We collect information you provide directly, such as your email
        address and name when you create an account...
      </p>

      {/* Add your full privacy policy content */}
    </div>
  );
}

Terms of Service

Create /app/terms/page.tsx with similar structure.

Tip: Use a service like Termly or Iubenda to generate compliant legal pages.


9. Adding New Pages

Marketing Pages

Create a new file in /app/:

// /app/about/page.tsx
import { Navbar } from '@/components/marketing/navbar';
import { Footer } from '@/components/marketing/footer';

export const metadata = {
  title: 'About Us - Your App Name',
  description: 'Learn about our mission and team.',
};

export default function AboutPage() {
  return (
    <div className="min-h-screen flex flex-col">
      <Navbar />
      <main className="flex-1 container py-12">
        <h1 className="text-4xl font-bold mb-8">About Us</h1>
        {/* Your content */}
      </main>
      <Footer />
    </div>
  );
}

Dashboard Pages

Create a new file in /app/dashboard/:

// /app/dashboard/analytics/page.tsx
export const metadata = {
  title: 'Analytics - Your App Name',
};

export default function AnalyticsPage() {
  return (
    <div className="space-y-8">
      <div>
        <h1 className="text-3xl font-bold">Analytics</h1>
        <p className="text-muted-foreground">
          View your usage statistics.
        </p>
      </div>

      {/* Your dashboard content */}
    </div>
  );
}

Don't forget to add it to the dashboard navigation in /config/navigation.ts.


10. Environment Variables Reference

All customizable environment variables:

# App
NEXT_PUBLIC_APP_URL=https://yourdomain.com

# Supabase
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=xxx
SUPABASE_SERVICE_ROLE_KEY=xxx

# Stripe
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_xxx
STRIPE_SECRET_KEY=sk_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx
NEXT_PUBLIC_STRIPE_PRICE_ID_FREE=price_xxx
NEXT_PUBLIC_STRIPE_PRICE_ID_PRO_MONTHLY=price_xxx
NEXT_PUBLIC_STRIPE_PRICE_ID_PRO_YEARLY=price_xxx
NEXT_PUBLIC_STRIPE_PRICE_ID_ENTERPRISE_MONTHLY=price_xxx
NEXT_PUBLIC_STRIPE_PRICE_ID_ENTERPRISE_YEARLY=price_xxx

# Resend
RESEND_API_KEY=re_xxx
EMAIL_FROM="Your App <noreply@yourdomain.com>"
EMAIL_REPLY_TO=support@yourdomain.com

File Locations Quick Reference

| What to Customize | File Location | |-------------------|---------------| | Site name/meta | /config/site.ts | | Pricing plans | /config/stripe.ts | | Navigation | /config/navigation.ts | | Colors/Theme | /app/globals.css | | Fonts | /app/layout.tsx | | Hero section | /components/marketing/hero.tsx | | Features | /components/marketing/features.tsx | | Testimonials | /components/marketing/testimonials.tsx | | FAQ | /components/marketing/faq.tsx | | Footer | /components/marketing/footer.tsx | | Navbar | /components/marketing/navbar.tsx | | Email templates | /emails/*.tsx | | Blog posts | /content/blog/*.mdx | | Images | /public/images/ | | Favicon | /app/favicon.ico |


Common Customization Questions

How do I remove the GitHub link from the footer?

Edit /components/marketing/footer.tsx and remove the GitHub item from the links array.

How do I change the number of pricing tiers?

Edit /config/stripe.ts. You can have 2, 3, 4, or more tiers. Just add or remove objects from the pricingPlans array.

How do I add a "Contact Sales" page instead of checkout for Enterprise?

  1. Create /app/contact/page.tsx with a contact form
  2. Update the Enterprise plan CTA to link to /contact instead of triggering checkout
  3. In /components/pricing-section.tsx, add logic to handle the Enterprise tier differently

How do I change the dashboard layout?

Edit /app/dashboard/layout.tsx for the overall structure, /components/dashboard/sidebar.tsx for the sidebar, and /components/dashboard/header.tsx for the header.

How do I add more OAuth providers?

  1. Enable the provider in Supabase Dashboard > Authentication > Providers
  2. Add a new OAuthButton in /components/auth-providers.tsx:
<OAuthButton provider="github">
  <GithubIcon className="mr-2 h-4 w-4" />
  Continue with GitHub
</OAuthButton>