How to hide your OpenAI API key in Next.js
In Next.js, only environment variables starting with NEXT_PUBLIC_ are sent to the browser. Everything else stays on the server. So the fix is two steps: rename the variable, and make the OpenAI call from server code.
1. Rename the variable
# .env.local (and in your host's environment settings)
OPENAI_API_KEY=sk-... # good: server only
# NEXT_PUBLIC_OPENAI_API_KEY # bad: shipped to every visitor
2. Call OpenAI from a route handler
// app/api/chat/route.js
export async function POST(req) {
const { message } = await req.json();
const res = await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.OPENAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "YOUR_MODEL", // pick from OpenAI's current model list
messages: [{ role: "user", content: message }],
}),
});
return Response.json(await res.json());
}
3. Call your route from the browser
const res = await fetch("/api/chat", {
method: "POST",
body: JSON.stringify({ message }),
});
Don't skip these
- If the key was ever public, rotate it in your OpenAI dashboard. Renaming doesn't un-leak it.
- Your route is now a free proxy to OpenAI for anyone who finds it. Add a rate limit or require sign-in, and set a monthly spending limit in your OpenAI account.