Vercel is the recommended hosting platform for Sabo. This guide covers importing your project, configuring environment variables, setting up production webhooks, and verifying your deployment works correctly.
Prerequisites
Before deploying, ensure you have:Required
Required
- Vercel account (Sign up free)
- Git repository (GitHub, GitLab, or Bitbucket) with your Sabo project pushed
- Supabase project configured with database migration applied (Database with Supabase)
- Local environment working (
pnpm devruns successfully with all features)
Optional (for full features)
Optional (for full features)
- Stripe account configured for payments (Setup guide)
- PostHog account for analytics (Setup guide)
- Custom domain (can be added after initial deployment)
Local build test: Run
pnpm build locally to catch any build errors before deploying.Step-by-Step Deployment
1
Import project to Vercel
Connect your repository to Vercel:
- Go to Vercel Dashboard
- Click Add New… → Project
- Select your Git provider and authorize access
- Choose your Sabo repository from the list
- Vercel will auto-detect Next.js settings:
- Framework Preset: Next.js
- Root Directory:
./(or./saboif using a monorepo) - Build Command:
pnpm run build(runs thebuildscript which callsnext build) - Output Directory:
.next(auto-detected) - Install Command:
pnpm install(auto-detected frompnpm-lock.yaml)
Sabo uses Next.js 16 with App Router. Vercel automatically detects the correct build configuration. No manual settings needed.
Project imported successfully. You should see the “Configure Project” screen.
2
Configure environment variables
Add all required environment variables in the Vercel project configuration screen. Click Environment Variables and add each variable below.
Core Variables (Required)
Stripe Variables (Required for payments)
PostHog Variables (Optional, for analytics)
PostHog is optional. Sabo only activates analytics if these variables are set.
Testing Variables (Optional, for E2E tests)
Only needed if running Playwright tests in CI/CD (e.g., GitHub Actions). Not required for deployment.
Environment Variable Scopes
For each variable, select the appropriate scope:- Production - Live site environment
- Preview - Pull request and branch preview deployments
- Development - Local development (usually not needed; use
.env.local)
All environment variables added and saved in Vercel.
3
Update Supabase Auth URLs
Configure Supabase to allow authentication from your Vercel domain:
- Go to Supabase Dashboard → Your Project
- Navigate to Authentication → URL Configuration
-
Update Site URL to:
(or your custom domain:
https://yourdomain.com) -
Add to Redirect URLs (comma-separated list):
-
For preview deployments, add a wildcard pattern:
The wildcard pattern (
https://*-your-project.vercel.app/auth/callback) allows all Vercel preview URLs to work with authentication. This is optional but recommended for testing auth in preview deployments.Supabase allows authentication callbacks from your Vercel domains.
4
Configure Stripe webhook (for payments)
Set up a production webhook endpoint in Stripe:
- Go to Stripe Dashboard
- Toggle to Live mode (top-right corner)
- Click Add endpoint
-
Set Endpoint URL to:
(Use your actual domain, not
.vercel.app) -
Select Events to send:
customer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedinvoice.payment_succeededinvoice.payment_failed
- Click Add endpoint
-
Copy the Signing secret (starts with
whsec_...) - Go back to Vercel Dashboard → Your Project → Settings → Environment Variables
-
Update
STRIPE_WEBHOOK_SECRETwith the new signing secret - Redeploy your project for the new secret to take effect
Stripe webhook endpoint created, signing secret added to Vercel, and project redeployed.
5
Deploy to production
Trigger your first deployment:Option A: Deploy from Vercel Dashboard
- In the Vercel project configuration screen, click Deploy
- Vercel will build your project and deploy it
- Monitor the build logs for errors
- Make a commit to your repository:
- Vercel automatically deploys on every push to your main branch
Build succeeds and deployment completes. You’ll see “Ready” status with a URL.
Build time: ~2-4 minutes for a fresh Sabo deployment. Subsequent deploys are faster (~1-2 minutes) thanks to caching.
6
Verify deployment
Test that your deployed application works correctly:
- Marketing Pages
- Authentication
- Dashboard
- Payments (Stripe)
Test public pages (no auth required):
- Homepage:
https://yourdomain.com/ - Pricing:
https://yourdomain.com/pricing - Contact:
https://yourdomain.com/contact - Blog:
https://yourdomain.com/blog - Changelog:
https://yourdomain.com/changelog - Legal pages:
/privacy,/terms-of-service,/cookie-policy
All marketing pages load correctly with proper styling and navigation.
All core features verified and working in production.
7
Add custom domain (optional)
Connect a custom domain to your Vercel project:
- Go to Vercel Dashboard → Your Project → Settings → Domains
- Click Add and enter your domain (e.g.,
yourdomain.com) - Follow DNS configuration instructions:
- For root domain (
yourdomain.com): Add A record pointing to Vercel’s IP - For subdomain (
www.yourdomain.com): Add CNAME record pointing tocname.vercel-dns.com
- For root domain (
- Wait for DNS propagation (usually 5-60 minutes)
- Vercel automatically issues SSL certificate via Let’s Encrypt
-
Update environment variable in Vercel:
-
Update Supabase Auth URLs:
- Site URL:
https://yourdomain.com - Add redirect URL:
https://yourdomain.com/auth/callback
- Site URL:
-
Update Stripe webhook endpoint URL:
- Change endpoint URL to:
https://yourdomain.com/api/webhooks/stripe - Copy new signing secret to Vercel env vars
- Change endpoint URL to:
- Redeploy your project for all changes to take effect
Custom domain is active with SSL, all URLs updated, and deployment successful.
8
Set up preview deployments
Vercel automatically creates preview deployments for every branch and pull request:
- Preview URLs:
https://your-project-git-branchname-yourteam.vercel.app - Pull request previews: Each PR gets a unique preview URL
- Automatic deployment: Push to any branch triggers a preview build
- Go to Vercel Dashboard → Your Project → Settings → Environment Variables
- Add variables with Preview scope
- Previews will use these instead of Production values
- Testing with Stripe test mode
- Using a staging Supabase database
- Sharing work-in-progress with your team
Preview deployments working. Each branch push creates a new preview URL.
Production Optimization
Performance
Sabo is optimized for Vercel out of the box:- Automatic CDN caching for static assets
- Edge runtime for fast middleware execution
- Image optimization via Next.js Image component
- Static generation for blog and changelog (built from MDX at deploy time—redeploy when content changes)
- Server-side rendering (SSR) for dynamic pages
No additional configuration needed. Vercel handles all optimizations automatically.
Build Settings
Default build settings work for most cases:Environment Management
Organize environment variables by environment:| Environment | Use Case | Example Keys |
|---|---|---|
| Production | Live site with real users | sk_live_..., production Supabase |
| Preview | PR/branch testing | sk_test_..., staging Supabase |
| Development | Local dev (.env.local) | sk_test_..., local Supabase |
Development environment variables are not synced to Vercel. Use
.env.local for local development.Troubleshooting
Build fails with 'Module not found' or TypeScript errors
Build fails with 'Module not found' or TypeScript errors
Symptoms:
- Build logs show module import errors
- TypeScript compilation fails
-
Verify all dependencies are in
package.json: -
Check for missing environment variables:
- Build-time code referencing env vars will fail if vars are missing
- Add missing vars in Vercel Dashboard
-
Clear build cache:
- Vercel Dashboard → Deployments → Latest build → … menu → Redeploy
- Check “Clear build cache and redeploy”
-
Local build test:
If it fails locally, fix errors before deploying.
Environment variables not working
Environment variables not working
Symptoms:
process.env.VARIABLE_NAMEisundefined- Features work locally but not in production
-
Check variable naming:
- Client-side variables must start with
NEXT_PUBLIC_ - Server-only variables should not have
NEXT_PUBLIC_prefix
- Client-side variables must start with
-
Verify variable scope:
- Go to Vercel Dashboard → Settings → Environment Variables
- Ensure variables have correct scope (Production/Preview/Development)
-
Redeploy after adding variables:
- Environment variables are only loaded at build time
- After adding/changing vars, trigger a new deployment
-
Check for typos:
- Variable names are case-sensitive
SUPABASE_URL≠SUPABASE_url
Authentication callback fails (Supabase)
Authentication callback fails (Supabase)
Symptoms:
- After signing in with OAuth, user sees error page
- Email verification links redirect to error page
- Console shows CORS or redirect errors
-
Check Supabase Redirect URLs:
- Go to Supabase Dashboard → Authentication → URL Configuration
- Ensure your Vercel domain is in Redirect URLs list
- Format:
https://yourdomain.com/auth/callback
-
Verify Site URL matches:
NEXT_PUBLIC_SITE_URLin Vercel must match Supabase Site URL- Include protocol (
https://), no trailing slash
-
Check for browser redirects:
- Open browser DevTools → Network tab
- Look for redirect chain
- Verify final redirect goes to
/auth/callback
-
Test with different browsers/incognito:
- Clear browser cache and cookies
- Try in incognito/private window
- Some browsers block third-party cookies
Stripe webhook not receiving events
Stripe webhook not receiving events
Symptoms:
- Subscriptions don’t update in database
- Payments succeed but user subscription status unchanged
- Stripe Dashboard shows “Endpoint not responding”
-
Verify endpoint URL is correct:
- Stripe Dashboard → Webhooks → Your endpoint
- URL should be:
https://yourdomain.com/api/webhooks/stripe - Must use custom domain, not
.vercel.app(for live mode)
-
Check webhook signing secret:
- Ensure
STRIPE_WEBHOOK_SECRETin Vercel matches endpoint secret - Use live mode secret (
whsec_...) for production
- Ensure
-
Test webhook delivery:
- Stripe Dashboard → Webhooks → Your endpoint
- Click Send test webhook
- Select event type (e.g.,
invoice.payment_succeeded) - Check Vercel logs for processing
-
Review Vercel Function Logs:
- Vercel Dashboard → Your Project → Logs
- Filter by
/api/webhooks/stripe - Look for errors or webhook signature verification failures
-
Ensure events are selected:
- Webhook endpoint must listen for:
customer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedinvoice.payment_succeededinvoice.payment_failed
- Webhook endpoint must listen for:
PostHog analytics not tracking events
PostHog analytics not tracking events
Symptoms:
- No events appear in PostHog dashboard
- Console shows “PostHog is not initialized”
-
Verify environment variables are set:
-
Redeploy after adding PostHog vars:
- PostHog only initializes if env vars are present at build time
-
Check browser console:
- Open DevTools → Console
- Look for PostHog initialization messages
- Check Network tab for requests to
app.posthog.com
-
Verify PostHog project is active:
- PostHog Dashboard → Project Settings
- Ensure project is not paused or archived
Production build is slow or times out
Production build is slow or times out
Symptoms:
- Vercel build exceeds time limit (10 minutes on free plan)
- Build gets stuck on specific step
-
Optimize dependencies:
-
Check for large files in repo:
- Avoid committing
node_modules/,.next/, or large assets - Use
.gitignoreto exclude build artifacts
- Avoid committing
-
Upgrade Vercel plan:
- Free tier: 10-minute build limit
- Pro tier: 45-minute build limit
-
Split large pages:
- Use dynamic imports for heavy components
- Implement code splitting for route segments
404 errors on page refresh
404 errors on page refresh
Symptoms:
- Direct URL navigation works
- Refreshing page shows 404
-
This should not happen with Vercel + Next.js App Router.
- Vercel automatically handles Next.js routing
-
Check Vercel routing configuration:
- Vercel Dashboard → Project Settings → General
- Ensure “Framework Preset” is set to Next.js
-
Verify build output:
- Check Vercel build logs
- Ensure
.nextdirectory contains expected routes
-
Test with
vercel dev:Run locally with Vercel’s dev server to debug routing
Continuous Deployment
Vercel automatically deploys on every push to your Git repository:Deployment Triggers
| Action | Result |
|---|---|
Push to main branch | Deploys to Production |
| Push to any other branch | Creates Preview deployment |
| Open pull request | Creates Preview with comment link |
| Merge PR | Deploys to Production |
Deployment Protection
Enable deployment protection for production:- Vercel Dashboard → Project Settings → Git
- Enable Production Deployment Protection
- Only designated team members can approve production deploys