Vercel Deployment
Deploy to Vercel with true runtime environment variables—change configs without rebuilding.
How It Works on Vercel
Vercel has built-in environment variable management. With next-dynenv:
- Set variables in Vercel's dashboard
- next-dynenv reads them at runtime (not build time)
- Changes take effect immediately without redeploying
Key Benefit Traditional Next.js on Vercel bakes NEXT_PUBLIC_* variables into the build. next-dynenv reads
them at runtime, so you can change variables without triggering a rebuild. :::
Basic Setup
1. Add PublicEnvScript
// app/layout.tsx
import { PublicEnvScript } from 'next-dynenv'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<PublicEnvScript />
</head>
<body>{children}</body>
</html>
)
}2. Configure Environment Variables
In your Vercel dashboard:
- Go to your project settings
- Navigate to "Environment Variables"
- Add your
NEXT_PUBLIC_*variables - Select which environments they apply to (Production, Preview, Development)
3. Deploy
vercel deployEnvironment-Specific Variables
Vercel allows different values per environment:
| Variable | Production | Preview | Development |
|---|---|---|---|
NEXT_PUBLIC_API_URL | https://api.prod.com | https://api.staging.com | http://localhost:8080 |
NEXT_PUBLIC_DEBUG | false | true | true |
Using vercel.json
You can also define environment variables in vercel.json:
{
"env": {
"NEXT_PUBLIC_APP_NAME": "MyApp"
},
"build": {
"env": {
"NEXT_PUBLIC_BUILD_TIME": "@build-time"
}
}
}For sensitive values, always use the Vercel dashboard instead of vercel.json. :::
Preview Deployments
Each pull request gets its own preview deployment. Set preview-specific variables:
NEXT_PUBLIC_API_URL (Preview) = https://api-preview.example.comEdge Functions
next-dynenv works with Vercel Edge Functions:
// middleware.ts
import { env } from 'next-dynenv'
import { NextResponse } from 'next/server'
export function middleware(request) {
const maintenanceMode = env('NEXT_PUBLIC_MAINTENANCE', 'false')
if (maintenanceMode === 'true') {
return NextResponse.redirect(new URL('/maintenance', request.url))
}
return NextResponse.next()
}Serverless Functions
// app/api/config/route.ts
import { env } from 'next-dynenv'
export function GET() {
return Response.json({
apiUrl: env('NEXT_PUBLIC_API_URL'),
environment: env('NEXT_PUBLIC_ENV', 'production'),
})
}Vercel CLI
Set environment variables via CLI:
# Add a variable
vercel env add NEXT_PUBLIC_API_URL
# List variables
vercel env ls
# Pull variables to local .env
vercel env pull .env.localImportant Considerations
Runtime vs Build Time
On Vercel, NEXT_PUBLIC_* variables set in the dashboard are available at both build time and runtime. next-dynenv ensures you get the runtime values, not stale build-time values.
Static Pages and ISR
If you're using static generation (SSG) or ISR, environment variables are captured at generation time:
// Pages with ISR revalidate periodically
export const revalidate = 60 // Env vars update every 60 seconds
export default function Page() {
return <div>...</div>
}For truly dynamic pages, PublicEnvScript automatically opts into dynamic rendering via connection():
import { PublicEnvScript } from 'next-dynenv'
export default function Page() {
return (
<html>
<head>
<PublicEnvScript /> {/* Automatically dynamic */}
</head>
<body>...</body>
</html>
)
}Deployment Checklist
Before deploying to Vercel, make sure you've:
- [ ] Added
PublicEnvScriptto your root layout - [ ] Set all
NEXT_PUBLIC_*variables in Vercel dashboard - [ ] Configured environment-specific values (Production, Preview, Development)
- [ ] Tested preview deployments with preview-specific variables
- [ ] Verified runtime values in deployed app (check browser console for
window.__ENV)
Next Steps
- Other Platforms - Railway, Fly.io, and more
- Security - Security best practices
- API Reference - Full API documentation