Why Vercel is the most natural path
KilatKoding uses Next.js App Router without a custom server requirement. Because of that, Vercel is usually the fastest deployment path, especially if you want preview deployments, custom domains, and clean env management.Before you begin
Make sure these are already true:- the repo can build locally,
npm run env:checklooks correct for the active features,- the production domain is already chosen,
- provider accounts such as Supabase, Midtrans, Doku, Resend, and the AI provider are ready if used.
Deployment steps
Create a Vercel project
Import the KilatKoding repo into Vercel. The default Next.js build command and output are usually detected automatically.
Fill environment variables
Copy the relevant env values from
.env.local or another secure source into Vercel. Focus only on the features that stay active.Set NEXT_PUBLIC_APP_URL to the production domain
Do not leave it as
http://localhost:3000. This value is used for metadata, callbacks, and order URLs.Env groups that are usually needed
| Group | Core env |
|---|---|
| Supabase | NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY, SUPABASE_SERVICE_ROLE_KEY |
| App URL | NEXT_PUBLIC_APP_URL |
| Midtrans payments | PAYMENT_PROVIDER=midtrans, MIDTRANS_SERVER_KEY, NEXT_PUBLIC_MIDTRANS_CLIENT_KEY |
| Doku payments | PAYMENT_PROVIDER=doku, DOKU_CLIENT_ID, DOKU_SECRET_KEY |
RESEND_API_KEY, EMAIL_FROM, optional CONTACT_EMAIL | |
| Admin | ADMIN_EMAILS |
| AI | AI_DEFAULT_PROVIDER, OPENAI_API_KEY or ANTHROPIC_API_KEY |
After deployment, do not forget provider-side config
Supabase
Supabase
Add these production URLs in redirect configuration:
Midtrans
Midtrans
Register the production webhook:Make sure the user return URL still points to your order page.
Doku
Doku
Register the production webhook:
Resend
Resend
Verify the sender domain and make sure
EMAIL_FROM uses a verified domain.Post-deploy validation
At minimum, check:- the homepage loads,
- login and signup work,
/dashboardopens for a logged-in user,/dashboard/billingworks if payments are active,/adminis reachable for admins if admin is active,GET /api/healthmatches expectations,- one sandbox payment and one webhook test succeed if payments are active.
Most common gotchas
| Problem | Usual cause |
|---|---|
| Auth callback fails | Supabase redirect URLs still point to the wrong domain |
| Checkout completes but the subscription is not active | The provider webhook still points to the old domain or signature verification fails |
| Contact form does not send | The Resend sender domain is not verified |
| Health check is degraded | An active feature is still missing required env |
| The order page still uses localhost | NEXT_PUBLIC_APP_URL was not updated |
Preview deployment vs production
Preview deployments are great for UI review, but:- do not use a preview URL as the final auth callback,
- do not use a preview URL as the final payment webhook target,
- use previews for layout and copy review, not as permanent integration endpoints.