Show HN: Made a boilerplate for SaaS and Freelancers to deploy in 24h

3 months ago 7

A comprehensive, production-ready SaaS starter kit with authentication, payments, admin dashboard, and many more features.

⚡ Quick Start: Complete setup in ≈30 minutes with our step-by-step guides below!


Check out the side bar for navigation →

  1. Project Overview
  2. Tech Stack & Architecture
  3. Quick Setup: Find & Replace Guide
  4. Prerequisites & Installation
  5. Project Structure
  6. Database Setup
  7. Authentication System
  8. Google OAuth Setup
  9. Session Persistence
  10. Stripe Payment Integration
  11. Customization Guide
  12. Deployment Guide
  13. Troubleshooting
  14. Best Practices
  15. API Reference

What is This Boilerplate?

This is a complete, production-ready SaaS boilerplate designed to help you launch your application in 24-72 hours. It includes everything you need to build a modern SaaS application with authentication, payments, user management, and more.

  • 🔐 User Authentication: Complete auth system with Supabase
  • 💳 Stripe Payments: Subscriptions & one-time payments
  • 📊 Admin Dashboard: Analytics, user management, revenue tracking
  • 📧 Email Integration: Transactional emails with Resend (Coming Soon)
  • 🎨 Modern UI: Beautiful, responsive design with Tailwind CSS
  • 📱 Mobile Responsive: Works perfectly on all devices
  • ⚡ Performance Optimized: Fast loading with Next.js 15
  • 🔒 Type-Safe: Full TypeScript support
  • 🧪 Ready to Test: Mock data for immediate testing
  • 💼 Multi-tenant Ready: Support for multiple businesses
  • 📈 Analytics Integration: Track user behavior and revenue
  • 🔔 Real-time Updates: Live notifications and data updates
  • 🌍 SEO Optimized: Built-in SEO best practices
  • 🔧 Highly Configurable: Easy to customize for any business

This boilerplate is perfect for:

  • SaaS Applications: Subscription-based software services
  • Business Directories: Managing companies and services
  • Lead Generation Platforms: Connecting clients with providers
  • E-learning Platforms: Online courses and training
  • Portfolio Websites: Showcasing work and services

🛠 Tech Stack & Architecture

  • Next.js 15: React framework with App Router
  • TypeScript: Type-safe development
  • Tailwind CSS: Utility-first CSS framework
  • Framer Motion: Smooth animations and transitions
  • Lucide React: Beautiful, customizable icons
  • Radix UI: Accessible component primitives
  • Supabase: Open-source Firebase alternative
  • PostgreSQL: Robust relational database
  • Row Level Security (RLS): Database-level security
  • Real-time subscriptions: Live data updates
  • Edge Functions: Serverless backend functions
  • Stripe: Complete payment processing
  • Resend: Modern email delivery**(Coming Soon)**
  • Webhooks: Real-time payment notifications
  • ESLint: Code quality and consistency
  • Prettier: Code formatting
  • PostCSS: CSS processing
  • Vercel Analytics: Performance monitoring
graph LR A[Frontend<br/>Next.js] --> B[API Layer<br/>Supabase] B --> C[Database<br/>PostgreSQL] A --> D[Payments<br/>Stripe] A --> E[Email<br/>Resend] A --> F[Analytics<br/>Vercel]
Loading
your-saas-boilerplate/ ├── src/ │ ├── app/ # Next.js App Router (pages, layouts, API routes) │ │ ├── api/ # API routes (REST endpoints, server actions) │ │ │ ├── auth/ # Authentication endpoints │ │ │ ├── webhooks/ # Stripe webhooks │ │ │ ├── admin/ # Admin API endpoints │ │ │ └── user/ # User management endpoints │ │ ├── admin/ # Admin dashboard pages │ │ │ ├── dashboard/ # Admin dashboard │ │ │ ├── analytics/ # Analytics page │ │ │ ├── all-users/ # User management │ │ │ └── newsletter/ # Newsletter management │ │ ├── auth/ # Authentication pages │ │ │ ├── signin/ # Sign-in page │ │ │ ├── callback/ # OAuth callback handler │ │ │ └── reset-password/ # Password reset │ │ ├── users/ # User dashboard │ │ │ └── dashboard/ # User dashboard page │ │ ├── marketplace/ # Repository marketplace │ │ ├── pricing/ # Pricing page │ │ ├── contact/ # Contact page │ │ ├── faq/ # FAQ page │ │ ├── success/ # Payment success page │ │ ├── cancel/ # Payment cancel page │ │ ├── privacy/ # Privacy policy │ │ ├── terms/ # Terms of service │ │ ├── globals.css # Global styles (Tailwind, color palette) │ │ ├── layout.tsx # Root layout (includes providers) │ │ └── page.tsx # Home page │ ├── components/ # Reusable UI and section components │ │ ├── layout/ # Layout components (Navbar, Footer, etc.) │ │ │ ├── Navbar.tsx │ │ │ ├── Footer.tsx │ │ │ └── DynamicFooter.tsx │ │ ├── auth/ # Authentication components │ │ │ ├── SignInForm.tsx │ │ │ ├── SignUpForm.tsx │ │ │ ├── ForgotPasswordForm.tsx │ │ │ └── ProtectedRoute.tsx │ │ ├── admin/ # Admin-specific components │ │ │ └── app-sidebar.tsx │ │ ├── dashboard/ # Dashboard components │ │ │ └── PurchasedRepositoriesCard.tsx │ │ ├── pricing/ # Pricing components │ │ │ └── PricingSection.tsx │ │ ├── sections/ # Page sections (hero, services, testimonials, forms, etc.) │ │ │ ├── hero/ │ │ │ ├── services/ │ │ │ ├── testimonials/ │ │ │ ├── forms/ │ │ │ └── sales/ │ │ ├── ui/ # Generic UI components (Button, Input, Select, Card, etc.) │ │ │ ├── Button.tsx │ │ │ ├── Input.tsx │ │ │ ├── Card.tsx │ │ │ └── badge.tsx │ │ ├── FAQ.tsx # FAQ component │ │ ├── RepositoryMarketplace.tsx │ │ └── SessionPersistenceWrapper.tsx │ ├── contexts/ # React contexts │ │ └── SiteSettingsContext.tsx │ ├── hooks/ # Custom React hooks │ │ ├── use-access-control.ts │ │ ├── use-customer-subscription.ts │ │ ├── use-mobile.tsx │ │ ├── use-pricing.ts │ │ └── use-session-persistence.ts │ └── lib/ # Utilities, configuration, and API clients │ ├── config.ts # Main site configuration (⚠️ CUSTOMIZE THIS) │ ├── auth.tsx # Authentication context and utilities │ ├── supabase.ts # Supabase client setup │ ├── supabase-client.ts # Client-side Supabase utilities │ ├── supabase-server.ts # Server-side Supabase utilities │ ├── database.types.ts # Generated database types (from Supabase) │ ├── stripe-client.ts # Stripe client setup │ ├── stripe-config.ts # Stripe configuration │ ├── stripe-pricing.ts # Stripe pricing utilities │ ├── session-manager.ts # Session persistence management │ ├── access-control.ts # User access control │ ├── customer-sync.ts # Customer synchronization │ ├── subscription.ts # Subscription management │ ├── github-api.ts # GitHub API integration │ ├── auth-actions.ts # Server auth actions │ └── utils.ts # General utilities ├── supabase/ # Database configuration and migrations │ ├── config.toml # Supabase configuration │ ├── migrations/ # Database migrations │ │ ├── 01_base_saas_setup.sql # Base SaaS tables and policies │ │ └── 05_boilerplate_management.sql # Repository marketplace tables │ └── manual_migrations/ # Additional migration files ├── public/ # Static assets │ ├── favicon.ico # Site favicon (⚠️ REPLACE WITH YOUR LOGO) │ ├── og-image.svg # Social sharing image (⚠️ REPLACE) │ └── *.svg # Various icons and images ├── data/ # Static data files ├── .env.example # Environment variables template ├── .env.local # Your environment variables (⚠️ CONFIGURE) ├── package.json # Dependencies and scripts ├── tailwind.config.js # Tailwind CSS configuration ├── next.config.ts # Next.js configuration ├── tsconfig.json # TypeScript configuration └── README.md # Project README

When setting up your boilerplate, these are the most important files to modify:

  • src/lib/config.ts - Main site configuration (company info, services, FAQ)
  • .env.local - Environment variables (API keys, database URLs)
  • tailwind.config.js - Colors and design system
  • public/favicon.ico - Your brand favicon
  • public/og-image.svg - Social sharing image
  • src/app/page.tsx - Homepage content
  • src/components/sections/hero/HeroMain.tsx - Hero section
  • src/components/FAQ.tsx - FAQ content (or configure in config.ts)
  • src/app/globals.css - Global styles and CSS variables
  • Component styles - Individual component styling

Quick Setup: Find & Replace Guide

🚀 INSTANT BRANDING UPDATE: Use this section to rebrand the entire project in under 5 minutes!

  1. Open VS Code Global Search: Press Shift + Cmd + F (Mac) or Shift + Ctrl + F (Windows)
  2. Copy each "Find" value from the tables below
  3. Paste into the search box and press Enter
  4. Copy the "Replace" value for your company
  5. Click "Replace All" (the replace icon) to update everything instantly

🏢 Core Branding Replacements

Find ThisReplace With Your DetailsWhat It Updates
[Your Company Name] Acme Corp Company name everywhere (navbar, footer, titles, FAQ, legal pages)
contact@[your-domain].com [email protected] All email references (contact forms, legal pages, auth emails)
noreply@[your-domain].com [email protected] System email sender address
https://[your-domain].com/ https://acmecorp.com/ Website URL in metadata and links
[email protected] [email protected] CRITICAL: Your admin access email
Find ThisReplace With Your HandleWhat It Updates
@[your-handle] @acmecorp Twitter/X handles in metadata
https://facebook.com/[your-handle] https://facebook.com/acmecorp Facebook page links
https://x.com/[your-handle] https://x.com/acmecorp X.com (Twitter) profile links
https://linkedin.com/company/[your-handle] https://linkedin.com/company/acmecorp LinkedIn company page
https://instagram.com/[your-handle] https://instagram.com/acmecorp Instagram profile links
https://youtube.com/@[your-handle] https://youtube.com/@acmecorp YouTube channel links

🎨 Logo & Favicon Replacement

Update Favicon (Browser Tab Icon)

  1. Create your favicon:
    • Easy option: Use Favicon.io or Canva to generate
    • Size: 32x32 or 16x16 pixels in .ico format
    • Alternative: Use PNG format (browsers support it)
  2. Replace the file: Replace src/app/favicon.ico with your own favicon
    • Location: The file must be exactly at src/app/favicon.ico
    • Name: Keep the filename as favicon.ico (no renaming needed)
  3. Verify: Clear browser cache (Cmd+Shift+R / Ctrl+F5) to see changes
  4. Pro tip: Test in multiple browsers to ensure it displays correctly

Update Logo in Navigation

  1. Add your logo: Place your logo image in public/ folder (e.g., public/logo.png)

  2. Find this in src/components/layout/Navbar.tsx:

    {/* Future users: Replace with your logo */} <Image src="/logo.png" alt="[Your Company Name]" width={120} height={40} />
  3. Update: Change the src, alt, width, and height to match your logo

Update Open Graph Image (Social Media Previews)

  1. Create OG image: 1200x630 pixels (PNG or JPG)
  2. Replace: public/reveal.png with your branded image
  3. Keep same filename or update references in src/app/layout.tsx

⚡ Advanced Replacements (Optional)

Business-Specific Content

  • Tagline: Search for "For Solopreneurs: Instantly Deploy Boilerplates" → Replace with your tagline
  • Description: Search for long description text in src/lib/config.ts → Update with your business description
  • Terms & Privacy: Update src/app/terms/page.tsx and src/app/privacy/page.tsx with your company's legal information

After running the replacements, verify these areas:

  • Navbar: Shows your company name and logo
  • Footer: Displays your contact info and social links
  • Login/Reset pages: Show your company name
  • Browser tab: Shows your favicon and page titles
  • Email settings: Admin email is YOUR email address
  • Legal pages: Company name appears in terms and privacy
  • FAQ section: References your company name
  • Meta tags: Social sharing shows your branding

IMMEDIATELY after setup, verify your admin email is correct:

  1. Go to src/lib/auth.tsx
  2. Find [email protected]
  3. Ensure it's replaced with YOUR actual email
  4. This gives you admin access to your application

📦 Prerequisites & Installation

  • Node.js: Version 18+ (LTS recommended)
  • npm: Version 9+ or yarn Version 1.22+
  • Git: Version control
  • Modern Browser: Chrome, Firefox, Safari, or Edge
# Clone your purchased boilerplate git clone [your-repo-url] cd your-project-name npm install

Step 2: Environment Setup

# Copy the example environment file cp .env.example .env.local # Edit .env.local with your keys (see configuration below)
# Run the base migration in Supabase SQL Editor # Copy/paste: supabase/migrations/01_base_saas_setup.sql

Step 4: Add Repository Management (Optional)

# If you want marketplace features, also run: # Copy/paste: supabase/migrations/05_boilerplate_management.sql
npm run dev # Visit <http://localhost:3000>

📋 Environment Configuration

Create a .env.local file with these variables:

# 🌐 Application URL NEXT_PUBLIC_BASE_URL=http://localhost:3000 # 🗄️ Supabase Configuration NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key # 💳 Stripe Configuration NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_your_publishable_key STRIPE_SECRET_KEY=sk_test_your_secret_key STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret # 📧 Email Configuration RESEND_API_KEY=your_resend_api_key [email protected] # 🔐 OAuth (Optional) SUPABASE_AUTH_EXTERNAL_GOOGLE_CLIENT_ID=your_google_client_id SUPABASE_AUTH_EXTERNAL_GOOGLE_SECRET=your_google_secret # 🐙 GitHub (Optional - for marketplace) GITHUB_TOKEN=your_github_token

1. Create Supabase Project

  1. Go to supabase.com
  2. Click "New Project"
  3. Choose your organization
  4. Set project name and database password
  5. Select region (choose closest to your users)
  6. Click "Create new project"
  1. Go to SettingsAPI
  2. Copy your Project URL and anon public key
  3. Copy your service_role secret key (keep this secure!)

3. Run Database Migrations

Base Migration (Required)

  1. Go to SQL Editor in Supabase
  2. Copy and run the SQL from supabase/migrations/01_base_saas_setup.sql

Repository Management (Optional)

  1. If you want other features visit Deplo.yt/marketplace to see all the SQL setups
  2. Copy and run the SQL you have purchase after the first.
  • user_profiles: Extended user information
  • subscriptions: Stripe subscription data
  • customers: Stripe customer data
  • prices: Product pricing information
  • products: Available products/plans
  • Row Level Security (RLS): Enabled on all tables
  • Real-time: Live data updates
  • Automatic backups: Daily backups included

  • Email/Password Authentication: Standard login system
  • Google OAuth: One-click social login
  • Password Reset: Secure password recovery
  • Email Verification: Confirm user email addresses
  • Protected Routes: Automatic route protection
  • Session Management: Persistent login sessions
  1. Registration: Users sign up with email/password or OAuth
  2. Verification: Email verification (optional)
  3. Login: Secure authentication with Supabase
  4. Session: Persistent sessions across browser restarts
  5. Protection: Automatic route protection for authenticated areas

The authentication system uses React Context for state management:

// Using the auth hook import { useAuth } from '@/lib/auth' function MyComponent() { const { user, signIn, signOut, loading } = useAuth() if (loading) return <div>Loading...</div> if (!user) return <div>Please sign in</div> return ( <div> <p>Welcome, {user.email}!</p> <button onClick={signOut}>Sign Out</button> </div> ) }

Wrap any page that requires authentication:

import { ProtectedRoute } from '@/components/auth/ProtectedRoute' export default function DashboardPage() { return ( <ProtectedRoute> <div>Protected content here</div> </ProtectedRoute> ) }

  1. Go to SupabaseAuthenticationProviders
  2. Enable Google
  3. Add your Google OAuth credentials
  4. Configure redirect URLs

Edit auth configuration in src/lib/config.ts:

auth: { signInRedirect: "/dashboard", // Where users go after sign in adminSignInRedirect: "/admin/dashboard", // Where admins go minPasswordLength: 6, // Password requirements }

Your application supports Google OAuth authentication alongside traditional email/password sign-in. Users can sign in with their Google accounts for a seamless, secure authentication experience.

  • One-Click Sign In: Users can sign in with their Google account
  • Secure Flow: Uses OAuth 2.0 with PKCE for enhanced security
  • Persistent Sessions: Google OAuth users get the same persistent sessions
  • Automatic Redirects: Seamless handling of OAuth callback flow

1. Create Google OAuth App

  1. Go to Google Cloud Console
  2. Create a new project or select existing one
  3. Enable Google+ API
  4. Go to CredentialsCreate CredentialsOAuth 2.0 Client ID
  5. Set Application type to Web application
  6. Add authorized redirect URIs:
    • http://localhost:3000/auth/callback (development)
    • https://yourdomain.com/auth/callback (production)
  7. Copy your Client ID and Client Secret
  1. Go to SupabaseAuthenticationProviders
  2. Enable Google
  3. Add your Google OAuth credentials:
    • Client ID: Your Google Client ID
    • Client Secret: Your Google Client Secret
  4. Save settings

3. Update Environment Variables

Add these to your .env.local:

# Google OAuth Configuration (Found in Supabase) SUPABASE_AUTH_EXTERNAL_GOOGLE_CLIENT_ID=your_google_client_id_here SUPABASE_AUTH_EXTERNAL_GOOGLE_SECRET=your_google_client_secret_here
  1. Visit your sign-in page
  2. Click "Continue with Google"
  3. Complete Google authentication
  4. Verify redirect to dashboard

The application includes an OAuth callback handler at src/app/auth/callback/page.tsx that:

  • Processes Google OAuth redirects
  • Validates sessions
  • Routes users to appropriate pages

Both sign-in and sign-up forms include Google OAuth buttons with:

  • Official Google button styling
  • Proper error handling
  • Loading states

Your application has 24-hour persistent sessions that keep users logged in across browser sessions, page refreshes, and device switching. This dramatically improves user experience by reducing authentication friction.

Extended Session Duration

  • Session Length: 24-hour sessions (86400 seconds)
  • Maximum Inactivity: 8 hours before auto-logout
  • Auto-refresh: Tokens refresh 5 minutes before expiry
  • Cross-browser: Sessions persist across browser restarts

Enhanced Session Management

  • Persistent Storage: Uses localStorage for cross-browser session persistence
  • Auto-Refresh: Automatic token refresh before expiration
  • Validation: Session validation on tab focus and visibility changes
  • Error Handling: Graceful handling of expired or invalid sessions

The SessionManager class (src/lib/session-manager.ts) provides:

  • Singleton Pattern: Ensures consistent session management
  • Automatic Refresh: Schedules token refresh 5 minutes before expiry
  • Session Validation: Checks and refreshes sessions on demand
  • Cleanup: Proper cleanup of timers and listeners

The Supabase client is configured for optimal session persistence:

export const supabase = createClient<Database>(supabaseUrl, supabaseAnonKey, { auth: { storage: typeof window !== 'undefined' ? window.localStorage : undefined, autoRefreshToken: true, persistSession: true, detectSessionInUrl: true, flowType: 'pkce' } })

Session Persistence Wrapper

The SessionPersistenceWrapper component:

  • Initializes session management on app load
  • Handles session validation and refresh
  • Manages session cleanup on unmount

Session persistence is automatically enabled. You can customize session behavior in:

Supabase Configuration (supabase/config.toml)

jwt_expiry = 86400 # 24 hours [auth.sessions] timebox = "24h" # Maximum session duration inactivity_timeout = "8h" # Logout after 8h inactivity

Modify session settings in src/lib/session-manager.ts if needed.


💳 Stripe Payment Integration

  • Subscription Management: Recurring billing with Stripe
  • One-time Payments: For marketplace purchases
  • Multiple Plans: Basic, Pro, Enterprise tiers
  • Webhook Integration: Real-time payment processing
  • Customer Portal: Let users manage their subscriptions
  • Invoice Generation: Automatic invoice creation
  1. Create a Stripe account
  2. Go to DevelopersAPI Keys
  3. Copy your Publishable Key and Secret Key

2. Create Products (Your prices)

Create these products in your Stripe Dashboard:

Subscription Plans:

  • Basic Plan: $29/month or $290/year
  • Pro Plan: $99/month or $990/year
  • Enterprise Plan: $299/month or $2990/year

One-time Products:

  • Repository Access: $99 per repository
  1. Go to DevelopersWebhooks
  2. Add endpoint: https://yourdomain.com/api/webhooks/stripe
  3. Select these events:
    • customer.subscription.created
    • customer.subscription.updated
    • customer.subscription.deleted
    • invoice.payment_succeeded
    • invoice.payment_failed

Add your Stripe keys to .env.local and update src/lib/stripe-config.ts:

export const stripeConfig = { plans: { basic: { monthly: "price_1234567890", // Your actual price ID yearly: "price_0987654321" }, pro: { monthly: "price_1111111111", yearly: "price_2222222222" } } }
  1. Subscription: User selects a plan
  2. Checkout: Redirect to Stripe Checkout
  3. Payment: User completes payment
  4. Webhook: Stripe notifies your app
  5. Access: User gains access to features

Use Stripe's test card numbers:

  • Success: 4242 4242 4242 4242
  • Decline: 4000 0000 0000 0002
  • 3D Secure: 4000 0000 0000 3220

1. Update Business Information

File: src/lib/config.ts

export const siteConfig = { // 🏢 Update these for your brand name: "Your Company Name", description: "Your company description and value proposition", tagline: "Your compelling tagline", // 📞 Update contact information contact: { email: "[email protected]", // phone: "+1 (555) 123-4567", // Uncomment if needed // address: "Your business address" // Uncomment if needed }, // 🌐 Update social media links social: { facebook: "<https://facebook.com/yourcompany>", x: "<https://x.com/yourcompany>", linkedin: "<https://linkedin.com/company/yourcompany>", instagram: "<https://instagram.com/yourcompany>" } }

Update the services section to match your offerings:

services: [ { id: "service1", name: "Your Primary Service", description: "Description of your main service offering", icon: "Star" // Choose from Lucide React icons }, { id: "service2", name: "Your Secondary Service", description: "Description of your second service", icon: "CheckCircle" } // Add more services as needed ]

3. Update Colors and Branding

File: tailwind.config.js

module.exports = { theme: { extend: { colors: { primary: { 50: '#eff6ff', 500: '#3b82f6', // Your primary color 600: '#2563eb', 900: '#1e3a8a', }, // Add your brand colors } } } }

4. Replace Logo and Images

Replace these files with your brand assets:

  • public/og-image.svg - Your logo for social sharing
  • public/favicon.ico - Your favicon
  • Update navbar logo in src/components/layout/Navbar.tsx

Update the FAQ section with your business-specific questions:

faq: [ { id: 1, question: "What services do you offer?", answer: "Detailed answer about your services...", category: "general" }, { id: 2, question: "How does pricing work?", answer: "Explanation of your pricing structure...", category: "billing" } // Add more relevant FAQ items ]
  1. Create the page file:
// src/app/new-feature/page.tsx export default function NewFeaturePage() { return ( <div className="container mx-auto px-4 py-8"> <h1 className="text-3xl font-bold">New Feature</h1> {/* Your content */} </div> ) }
  1. Add navigation: Update navigation in src/components/layout/Navbar.tsx
// src/components/NewComponent.tsx 'use client' import { useState } from 'react' export function NewComponent() { const [state, setState] = useState('') return ( <div className="p-4 border rounded-lg"> {/* Your component */} </div> ) }

Customizing Email Templates

Update email templates in your email provider (Resend) or create custom templates in src/lib/email-templates.ts


  • ✅ Database migrations completed in Supabase
  • ✅ All environment variables configured
  • ✅ Stripe products created and configured
  • ✅ Custom domain ready (optional)
  • ✅ Tested locally with npm run dev

Vercel Deployment (Recommended)

Step 1: Prepare Repository

# Ensure your code is pushed to GitHub git add . git commit -m "Ready for deployment" git push origin main
  1. Go to vercel.com
  2. Sign in with GitHub
  3. Click "New Project"
  4. Select your repository
  5. Configure environment variables (see below)
  6. Click "Deploy"

Step 3: Environment Variables for Production

Add these in Vercel dashboard:

# 🌐 Application URL (IMPORTANT: Update this!) NEXT_PUBLIC_BASE_URL=https://your-domain.vercel.app # 🗄️ Database (Production Supabase) NEXT_PUBLIC_SUPABASE_URL=https://your-prod-project.supabase.co NEXT_PUBLIC_SUPABASE_ANON_KEY=your_production_anon_key SUPABASE_SERVICE_ROLE_KEY=your_production_service_role_key # 💳 Stripe (LIVE KEYS for production!) NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_... STRIPE_SECRET_KEY=sk_live_... STRIPE_WEBHOOK_SECRET=whsec_... # 📧 Email RESEND_API_KEY=your_resend_api_key [email protected]

1. Update Stripe Webhooks

  1. Go to Stripe DashboardDevelopersWebhooks
  2. Update endpoint URL to: https://your-domain.vercel.app/api/webhooks/stripe
  3. Test webhook delivery
  1. Go to SupabaseAuthenticationURL Configuration
  2. Add your domain to Site URL: https://your-domain.vercel.app
  3. Add to Redirect URLs: https://your-domain.vercel.app/auth/callback
  • User registration works
  • Login/logout works
  • Payments process correctly
  • Admin dashboard accessible
  • Emails send successfully
  1. Go to your project in Vercel
  2. Click "Domains"
  3. Add your custom domain
  4. Follow DNS configuration instructions

2. Update Environment Variables

Update NEXT_PUBLIC_BASE_URL to your custom domain

3. Update Stripe and Supabase

Update webhook URLs and redirect URLs to use your custom domain


Common Issues and Solutions

Problem: "Invalid login credentials" Solution:

  • Check if user exists in Supabase Auth
  • Verify email confirmation if required
  • Check RLS policies are correctly set

Problem: OAuth not working Solution:

  • Verify OAuth provider configuration
  • Check redirect URLs match exactly
  • Ensure OAuth app is approved/published

Problem: Stripe webhooks failing Solution:

  • Check webhook endpoint URL
  • Verify webhook secret matches
  • Check Vercel function logs for errors

Problem: Subscription not activating Solution:

  • Check webhook events are properly handled
  • Verify database updates in webhook handler
  • Check Stripe dashboard for successful payments

Problem: RLS policies blocking access Solution:

  • Review RLS policies in Supabase
  • Check user authentication state
  • Verify policy conditions match your use case

Problem: Migration errors Solution:

  • Run migrations in correct order
  • Check for foreign key constraints
  • Verify table dependencies

Problem: Build failing on Vercel Solution:

  • Check for TypeScript errors
  • Verify all dependencies are installed
  • Check environment variables are set

Problem: Environment variables not working Solution:

  • Ensure variables start with NEXT_PUBLIC_ for client-side
  • Redeploy after changing environment variables
  • Check for typos in variable names
  1. Check the Console: Browser dev tools often show helpful error messages
  2. Review Logs: Check Vercel function logs and Supabase logs
  3. Test in Isolation: Test components individually to isolate issues
  4. Community Support: Join relevant Discord/Slack communities
  • Use Next.js Image component
  • Optimize images before uploading
  • Consider using a CDN
  • Use proper indexes on frequently queried columns
  • Implement pagination for large datasets
  • Use Supabase Edge Functions for complex queries
  • Implement React Query for data fetching
  • Use Next.js built-in caching features
  • Consider Redis for session storage

src/ ├── app/ # Pages and API routes ├── components/ # Reusable components │ ├── ui/ # Basic UI components │ ├── layout/ # Layout components │ ├── sections/ # Page sections │ └── features/ # Feature-specific components ├── lib/ # Utilities and configuration ├── hooks/ # Custom React hooks └── contexts/ # React contexts
  • Components: PascalCase (UserProfile.tsx)
  • Files: camelCase (formatDate.ts)
  • Constants: UPPER_SNAKE_CASE (MAX_FILE_SIZE)
  • Variables: camelCase (userName)
// External libraries first import React from 'react' import { useState, useEffect } from 'react' // Internal components import { Button } from '@/components/ui/Button' import { Navbar } from '@/components/layout/Navbar' // Utilities and types import { formatDate } from '@/lib/utils' import type { User } from '@/types'
  • Always use Row Level Security (RLS)
  • Validate data on both client and server
  • Use prepared statements for dynamic queries
  • Regularly update dependencies
  • Enforce strong password requirements
  • Implement rate limiting on auth endpoints
  • Use secure session management
  • Validate user permissions on every request
  • Validate all input data
  • Use HTTPS in production
  • Implement proper error handling
  • Don't expose sensitive data in responses

Performance Best Practices

  • Use React.memo for expensive components
  • Implement proper key props in lists
  • Lazy load components when possible
  • Optimize re-renders with useMemo and useCallback
  • Use proper indexes
  • Implement pagination
  • Avoid N+1 queries
  • Use database functions for complex operations
  • Use semantic HTML
  • Implement proper meta tags
  • Add structured data markup
  • Optimize page loading speeds

Register a new user

Request Body:

{ "email": "[email protected]", "password": "securepassword", "firstName": "John", "lastName": "Doe" }

Response:

{ "user": { "id": "...", "email": "..." }, "session": { "access_token": "...", "refresh_token": "..." } }

Sign in an existing user

Request Body:

{ "email": "[email protected]", "password": "securepassword" }

POST /api/create-checkout-session

Create a Stripe checkout session

Request Body:

{ "priceId": "price_1234567890", "mode": "subscription", // or "payment" "successUrl": "<https://yoursite.com/success>", "cancelUrl": "<https://yoursite.com/cancel>" }

POST /api/webhooks/stripe

Handle Stripe webhooks (internal use)

User Management Endpoints

Get current user profile

Response:

{ "id": "...", "email": "...", "firstName": "...", "lastName": "...", "subscription": { "status": "active", "plan": "pro" } }

Update user profile

Request Body:

{ "firstName": "John", "lastName": "Doe", "company": "Acme Corp" }

Get all users (admin only)

Query Parameters:

  • page: Page number (default: 1)
  • limit: Items per page (default: 10)
  • search: Search term

Get analytics data (admin only)

Response:

{ "totalUsers": 150, "totalRevenue": 25000, "newUsersThisMonth": 25, "churnRate": 2.5 }

Congratulations! You now have a complete understanding of your SaaS boilerplate. With this documentation, you should be able to:

  • ✅ Set up your development environment
  • ✅ Customize the application for your business
  • ✅ Deploy to production
  • ✅ Troubleshoot common issues
  • ✅ Scale your application as it grows
  1. Customize for Your Business: Update branding, content, and features
  2. Test Everything: Ensure all features work with your specific setup
  3. Deploy to Production: Follow the deployment guide
  4. Monitor and Iterate: Use analytics to improve your application

Remember to:

  • Keep your dependencies updated
  • Monitor your application performance
  • Backup your database regularly
  • Follow security best practices

Happy building! 🚀


This documentation was generated for your SaaS boilerplate. Update it as you customize and extend your application.

Read Entire Article