Is Nuxt runtimeConfig public? Keeping API keys out of the browser
Only part of it. Keys you put directly under runtimeConfig in nuxt.config stay on the server. Keys under runtimeConfig.public are exposed to the client and can appear in the page payload. An API key in the public block is public.
How the two blocks work
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
openaiApiKey: "", // server only; set with NUXT_OPENAI_API_KEY
public: {
apiBase: "/api", // exposed to the client; set with NUXT_PUBLIC_API_BASE
},
},
});
Nuxt can override declared runtime config keys with matching environment variables. Private runtime config uses the NUXT_ prefix; public config uses NUXT_PUBLIC_. Declaring a key does not make every environment variable public: only values placed in runtimeConfig.public are exposed to the client.
Why keys still end up in public config
- The browser code needed the key, so it was moved into
publicto make an error go away. - A server-only value was read on the server and then passed to the page, for example through
useStateor rendered HTML. - The provider is called from a component instead of a server route. See why that exposes the key.
Call the provider from a server route
Keep the key in the private runtime config and make the call from server/api:
// server/api/chat.post.ts
export default defineEventHandler(async (event) => {
const { openaiApiKey } = useRuntimeConfig(event);
const { message } = await readBody(event);
return await $fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: { Authorization: "Bearer " + openaiApiKey },
body: {
model: "YOUR_MODEL",
messages: [{ role: "user", content: message }],
},
});
});
Your client calls /api/chat and never receives the key. Passing event to useRuntimeConfig ensures the server route reads the runtime value for that request.
Set the variable on your host
Nuxt's CLI reads .env during development and build commands, but the built server does not read that file at runtime. Set NUXT_OPENAI_API_KEY in your hosting platform's environment settings and redeploy or restart as that platform requires.
Check your live site
- Open your site, view the page source, and search for your key's prefix and names from the
publicblock. - If a secret appears, rotate it first. Moving it does not un-leak it. Follow these steps for a leaked API key.
- Add authentication or rate limits to your server route, and set a spending limit with the provider.