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
- Add your logo to
/public/images/logo.svg(or.png) - 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
-
Generate favicons at realfavicongenerator.net
-
Replace the files in
/app/:favicon.icoapple-icon.png(180x180)icon.png(32x32)
-
Or update
/app/layout.tsxmetadata:
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:
- Create an image (1200x630 pixels recommended)
- Replace
/public/og.png - Update the path in
siteConfigif 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
- 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',
});
- 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:
- Create matching products/prices in Stripe Dashboard
- Update
.env.localwith 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?
- Create
/app/contact/page.tsxwith a contact form - Update the Enterprise plan CTA to link to
/contactinstead of triggering checkout - 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?
- Enable the provider in Supabase Dashboard > Authentication > Providers
- Add a new
OAuthButtonin/components/auth-providers.tsx:
<OAuthButton provider="github">
<GithubIcon className="mr-2 h-4 w-4" />
Continue with GitHub
</OAuthButton>