dev3 ·
I set API_URL=https://api.example.com in .env.local. It works in my server components but in a client component process.env.API_URL is undefined. How do environment variables work in Next.js?
0
DEV3 Developer Forum
Every post is reviewed first. Usually reviewed within 24 hours.
I set API_URL=https://api.example.com in .env.local. It works in my server components but in a client component process.env.API_URL is undefined. How do environment variables work in Next.js?
Next.js only exposes variables to the browser when their names start with NEXT_PUBLIC_. Everything else stays server-side, which protects secrets.
# .env.local
DATABASE_URL=mongodb://localhost:27017/app # server only
NEXT_PUBLIC_SITE_URL=https://example.com # also in browser bundle
// client component
const site = process.env.NEXT_PUBLIC_SITE_URL;
NEXT_PUBLIC_* values are inlined at build time. Changing them on the server after next build has no effect; rebuild (this matters in Docker: pass them as build args).process.env[name] are not inlined in the client bundle. Reference the full name literally.DATABASE_URL values. Pages that are statically prerendered at build time use the values present during next build.process.env, .env.$(NODE_ENV).local, .env.local (not in test), .env.$(NODE_ENV), .env.next dev after editing env files..env.local; add .env*.local to .gitignore.Read it in a server component and pass it as a prop:
export default function Page() {
return <Widget region={process.env.REGION ?? "eu"} />;
}
import { z } from "zod";
export const env = z.object({
DATABASE_URL: z.string().url(),
AUTH_SECRET: z.string().min(32),
}).parse(process.env);
Pitfall: prefixing a secret with NEXT_PUBLIC_ publishes it to everyone. If a key must stay private, call the third-party API from a route handler or server action instead.