
About
Expert knowledge for deploying to Vercel with Next.js
name: vercel-deployment description: Expert knowledge for deploying to Vercel with Next.js risk: safe source: vibeship-spawner-skills (Apache 2.0) date_added: 2026-02-27
Vercel Deployment
Expert knowledge for deploying to Vercel with Next.js
Capabilities
- vercel
- deployment
- edge-functions
- serverless
- environment-variables
Prerequisites
- Required skills: nextjs-app-router
Patterns
Environment Variables Setup
Properly configure environment variables for all environments
When to use: Setting up a new project on Vercel
// Three environments in Vercel: // - Development (local) // - Preview (PR deployments) // - Production (main branch)
// In Vercel Dashboard: // Settings → Environment Variables
// PUBLIC variables (exposed to browser) NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
// PRIVATE variables (server only) SUPABASE_SERVICE_ROLE_KEY=eyJ... // Never NEXT_PUBLIC_! DATABASE_URL=postgresql://...
// Per-environment values: // Production: Real database, production API keys // Preview: Staging database, test API keys // Development: Local/dev values (also in .env.local)
// In code, check environment: const isProduction = process.env.VERCEL_ENV === 'production' const isPreview = process.env.VERCEL_ENV === 'preview'
Edge vs Serverless Functions
Choose the right runtime for your API routes
When to use: Creating API routes or middleware
// EDGE RUNTIME - Fast cold starts, limited APIs // Good for: Auth checks, redirects, simple transforms
// app/api/hello/route.ts export const runtime = 'edge'
export async function GET() { return Response.json({ message: 'Hello from Edge!' }) }
// middleware.ts (always edge) export function middleware(request: NextRequest) { // Fast auth checks here }
// SERVERLESS (Node.js) - Full Node APIs, slower cold start // Good for: Database queries, file operations, heavy computation
// app/api/users/route.ts export const runtime = 'nodejs' // Default, can omit
export async function GET() { const users = await db.query('SELECT * FROM users') return Response.json(users) }
Build Optimization
Optimize build for faster deployments and smaller bundles
When to use: Preparing for production deployment
// next.config.js /** @type {import('next').NextConfig} */ const nextConfig = { // Minimize output output: 'standalone', // For Docker/self-hosting
// Image optimization images: { remotePatterns: [ { hostname: 'your-cdn.com' }, ], },
// Bundle analyzer (dev only) // npm install @next/bundle-analyzer ...(process.env.ANALYZE === 'true' && { webpack: (config) => { const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer') config.plugins.push(new BundleAnalyzerPlugin()) return config }, }), }
// Reduce serverless function size: // - Use dynamic imports for heavy libs // - Check bundle with: npx @next/bundle-analyzer
Preview Deployment Workflow
Use preview deployments for PR reviews
When to use: Setting up team development workflow
// Every PR gets a unique preview URL automatically
// Protect preview deployments with password: // Vercel Dashboard → Settings → Deployment Protection
// Use different env vars for preview: // - PREVIEW: Use staging database // - PRODUCTION: Use production database
// In code, detect preview: if (process.env.VERCEL_ENV === 'preview') { // Show "Preview" banner // Use test payment processor // Disable analytics }
// Comment preview URL on PR (automatic with Vercel GitHub integration)
Custom Domain Setup
Configure custom domains with proper SSL
When to use: Going to production
// In Vercel Dashboard → Domains
// Add domains: // - example.com (apex/root) // - www.example.com (subdomain)
// DNS Configuration (at your registrar): // Type: A, Name: @, Value: 76.76.21.21 // Type: CNAME, Name: www, Value: cname.vercel-dns.com
// Redirect www to apex (or vice versa): // Vercel handles this automatically
// In next.config.js for redirects: module.exports = { async redirects() { return [ { source: '/old-page', destination: '/new-page', permanent: true, // 308 }, ] }, }
Sharp Edges
NEXT_PUBLIC_ exposes secrets to the browser
Severity: CRITICAL
Situation: Using NEXT_PUBLIC_ prefix for sensitive API keys
Symptoms:
- Secrets visible in browser DevTools → Sources
- Security audit finds exposed keys
- Unexpected API access from unknown sources
Why this breaks: Variables prefixed with NEXT_PUBLIC_ are inlined into the JavaScript bundle at build time. Anyone can view them in browser DevTools. This includes all your users and potential attackers.
Recommended fix:
Only use NEXT_PUBLIC_ for truly public values:
// SAFE to use NEXT_PUBLIC_ NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ... // Anon key is designed to be public NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_l
