The Gap Nobody Warns You About
You built the app. It works on your machine. You're ready to show the world.
Then you deploy and everything breaks.
This isn't a skill issue. It's the predictable result of how AI coding tools work. Lovable, Bolt, and Cursor are optimized for building — not deploying. They generate working code in a development environment where everything is permissive: localhost has no CORS restrictions, environment variables sit in a .env file three feet from your code, and your database accepts connections from anywhere.
Production is a different planet. Secrets must be injected. Domains must resolve. Databases must be locked down. Auth must redirect to the right URL. Payments must use live keys.
The gap between "works locally" and "works in production" has killed more launches than bad ideas ever have. This guide closes that gap.
The Pre-Deploy Checklist
Before you touch a deploy button, walk through every item below. Skip one and you'll spend hours debugging something that takes 30 seconds to configure correctly.
1. Environment Variables
This is the #1 cause of broken deploys. Full stop.
In development, your secrets live in .env.local or .env:
# .env.local (development) NEXT_PUBLIC_SUPABASE_URL=https://abc123.supabase.co NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGci... SUPABASE_SERVICE_ROLE_KEY=eyJhbGci... STRIPE_SECRET_KEY=sk_test_abc123 STRIPE_WEBHOOK_SECRET=whsec_test_xyz
# Quick way to find all env vars your project uses grep -r "process.env" --include="<em>.ts" --include="</em>.tsx" --include="<em>.js" src/
-- Check which tables have RLS disabled SELECT tablename FROM pg_tables WHERE schemaname = 'public' AND tablename NOT IN ( SELECT tablename FROM pg_tables WHERE rowsecurity = true );
Connection pooling: If your app might handle more than a handful of concurrent users, enable connection pooling in Supabase (Project Settings → Database → Connection Pooling). Use the pooled connection string in production.
Migrations: If you made schema changes by clicking around in the Supabase dashboard, document them. You'll need to replicate those changes if you ever set up a staging environment or migrate.
3. Authentication Redirect URLs
Every auth provider — Supabase Auth, Clerk, Auth0, NextAuth — has a list of allowed redirect URLs. In development, that list includes http://localhost:3000.
In production, it must include your actual domain.
Supabase Auth: Go to Authentication → URL Configuration. Add your production URL (https://yourdomain.com) to the Site URL and Redirect URLs.
OAuth providers (Google, GitHub, etc.): Log into each provider's developer console and add your production callback URL. For Supabase + Google, that's:
https://your-project-ref.supabase.co/auth/v1/callback
Miss this and your users will see "redirect_uri_mismatch" errors when they try to log in. It's the second most common post-deploy complaint on Reddit.
4. Payments: Test to Live
If you're using Stripe:
sk_test_...) will not work in live mode.https://yourdomain.com/api/webhooks/stripewhsec_live_...) and add it to your production env vars..env.local for development.# Production env vars for Stripe STRIPE_SECRET_KEY=sk_live_... # NOT sk_test_ STRIPE_WEBHOOK_SECRET=whsec_live_... # NOT whsec_test_ NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_...
5. Domain and DNS
Buy a domain from Namecheap, Cloudflare, or Google Domains. Then point it at your hosting:
For Vercel: Add your domain in Project Settings → Domains. Vercel will tell you exactly which DNS records to create. Usually a CNAME pointing to cname.vercel-dns.com or an A record.
For Railway: Go to your service's Settings → Networking → Custom Domain. Railway gives you a CNAME target.
SSL certificates are automatic on both Vercel and Railway. You don't need to configure anything — they provision certs through Let's Encrypt once DNS propagates.
DNS propagation takes anywhere from 5 minutes to 48 hours. Don't panic if it's not instant.
Platform-Specific Deployment
From Lovable → Vercel
.env.local into Vercel's Environment Variables section.- Lovable gotchas:
- Lovable projects sometimes use Vite instead of Next.js. Make sure Vercel detects the right framework.
- If the build fails, check for hardcoded
localhostreferences. Search your codebase forlocalhost:and replace them with environment variables or relative URLs. - Lovable's Supabase integration may have set up auth redirects only for the Lovable preview URL. Update them.
From Bolt → Railway or Vercel
- Bolt gotchas:
- Bolt projects sometimes have dependencies that aren't in
package.json. If the build fails with "module not found," install the missing package and push again. - Check for any Bolt-specific API endpoints that won't exist in your self-hosted version.
From Cursor → Vercel, Railway, or Cloudflare
Cursor gives you a standard codebase, so deployment is the most straightforward:
- Cursor gotchas:
- Cursor-generated code sometimes imports from absolute paths that work locally but break in production. If you see path resolution errors, check your
tsconfig.jsonpaths configuration. - AI-generated code loves
console.log. It won't break anything, but clean up sensitive data logging before production.
What Breaks After Deploy
You deployed. The build succeeded. You open the URL and... something's wrong. Here's what to check, in order of likelihood.
CORS Errors
Symptom: API calls fail in the browser console with "Access-Control-Allow-Origin" errors.
Cause: Your API is on a different domain than your frontend, and CORS headers aren't configured.
Fix: If you're using Next.js API routes, this usually isn't an issue since the API and frontend share a domain. If you have an external API, add CORS headers:
// In your API route or middleware
const headers = {
'Access-Control-Allow-Origin': 'https://yourdomain.com',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
};grep -r "localhost" --include="<em>.ts" --include="</em>.tsx" src/
npx @sentry/wizard@latest -i nextjs
This sets up client and server error tracking in about 2 minutes. Once it's running, Sentry emails you when new errors appear in production — with the exact stack trace, the user's browser, and what they were doing.
3. Uptime Monitoring
Use Better Uptime (free tier) or UptimeRobot (free tier). Point it at your production URL. It pings your site every few minutes and texts/emails you if it goes down.
You will feel much calmer knowing you'll be notified if something breaks at 2 AM instead of finding out from an angry user at 9 AM.
The One-Week Post-Launch Checklist
Your app is live. The first week is when most problems surface. Run through this daily:
- Day 1-2: Watch everything.
- ☐Check error tracking for new issues.
- ☐Review logs for 500 errors or unusual patterns.
- ☐Confirm real users can sign up, log in, and complete the core flow.
- ☐Verify payments process end-to-end (if applicable).
- Day 3-4: Fix and harden.
- ☐Fix any errors that appeared in Sentry.
- ☐Check database performance — slow queries show up fast with real traffic.
- ☐Verify email delivery (confirmation emails, password resets).
- ☐Test on mobile if you haven't already.
- Day 5-7: Optimize and prepare to scale.
- ☐Check your hosting bill — make sure nothing unexpected is running.
- ☐Review your Supabase usage against your plan limits.
- ☐Set up database backups if you haven't (Supabase does daily backups on paid plans).
- ☐Remove any test data or dummy accounts from production.
The Bottom Line
The deploy step isn't glamorous. There's no AI tool that automates all of it for you (yet). But it's predictable — the same dozen things break every time.
Run the checklist. Set up monitoring. Check your logs daily for the first week.
The builders who ship consistently aren't the ones who never hit deploy issues. They're the ones who know exactly where to look when something breaks.
Your app works locally. Now make it work for everyone else.