Runtime Config (useRuntimeConfig)
Runtime Config (useRuntimeConfig)
Level 6 — SEO & Configuration The secure configuration system used to manage environment variables (
.env), explicitly separating private backend secrets from public frontend keys.
1. Prerequisites
nuxt.config.ts— Where the Runtime Config schema is defined.- Node.js (Runtime Environment) — The server environment hosting standard process configs.
2. Term Category
Security & Middleware (Environment & Server Secret Configuration): runtimeConfig manages environment variables, keeping private API secret keys isolated to the server while exposing public variables to the client.
3. Explanation
Environment Context
- Server & Client
(1) Design Motivation — "Why did we design this?"
In a Node.js app, you read environment variables using process.env.MY_SECRET.
In a Vite/Vue app, you read them using import.meta.env.VITE_MY_SECRET.
Because Nuxt is a full-stack framework spanning both Node (Nitro) and the Browser (Vite), checking .env variables becomes a nightmare. Even worse, if you accidentally expose a backend database password to the browser, your entire system is compromised.
Runtime Config creates a single, unified, strictly-typed API (useRuntimeConfig) to access environment variables. It enforces a strict separation between what is safely sent to the browser and what is locked on the server.
(2) Defining the Config
You must explicitly define your runtime config schema inside nuxt.config.ts.
- Any key placed directly inside
runtimeConfigis PRIVATE (Server-only). - Any key placed inside
runtimeConfig.publicis PUBLIC (Server & Client).
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
// Private keys: NEVER sent to the browser.
// Nuxt automatically populates this with process.env.STRIPE_SECRET_KEY
stripeSecretKey: '',
databasePassword: '',
public: {
// Public keys: Sent to the browser payload.
// Nuxt automatically populates this with process.env.NUXT_PUBLIC_API_BASE
apiBaseUrl: '/api'
}
}
})
(3) Using the Config
To access the variables in your Vue components or Nitro server routes, you use the auto-imported useRuntimeConfig() composable.
<!-- pages/index.vue -->
<script setup lang="ts">
const config = useRuntimeConfig();
// Works perfectly in the browser!
console.log(config.public.apiBaseUrl);
// If you try to access this in the browser, it will be undefined!
// It is only accessible inside Nitro server routes.
console.log(config.stripeSecretKey);
</script>
4. Common Mistakes & Pitfalls
Mistake 1: Trusting .env files blindly without defining them in nuxt.config.ts
The mistake: Adding MY_API_KEY=123 to a .env file and trying to access it using process.env.MY_API_KEY inside a Vue component.
Why it's wrong: Nuxt 3 purposely restricts raw process.env access in Vue components to prevent accidental security leaks.
Golden Rule: Every environment variable you intend to use MUST be explicitly defined in the runtimeConfig object in nuxt.config.ts, and accessed via useRuntimeConfig().
Mistake 2: Exposing Private Server Keys by Putting Them in runtimeConfig.public
The mistake: Placing database password inside runtimeConfig.public.dbPassword in nuxt.config.ts.
Why it's wrong: Any property placed under runtimeConfig.public is serialized into client JavaScript bundles sent to the browser. Keep server secrets at top-level runtimeConfig.
Incorrect:
export default defineNuxtConfig({
runtimeConfig: {
public: {
dbSecret: 'password' // ❌ Exposed to browser client bundles!
}
}
});
Fix:
export default defineNuxtConfig({
runtimeConfig: {
dbSecret: 'password', // Private server-only property
public: {
apiBase: 'https://api.example.com' // Public client property
}
}
});
Mistake 3: Attempting to Access Private runtimeConfig Keys inside Client Components
The mistake: Calling const config = useRuntimeConfig(); console.log(config.dbSecret) inside a Client Component.
Why it's wrong: Private runtimeConfig keys exist ONLY on the server environment. On the client browser, private keys evaluate to undefined.
Incorrect:
<script setup>
const config = useRuntimeConfig();
console.log(config.dbSecret); // ❌ Undefined on client browser!
</script>
Fix:
<script setup>
const config = useRuntimeConfig();
console.log(config.public.apiBase); // Access public runtimeConfig properties on client
</script>
5. Practice Exercises
Exercise 1: Configuring Server-Private vs Public Runtime Config
Scenario:
Define a server-only private API secret and a public API base URL in nuxt.config.ts.
Requirements:
- Define
runtimeConfigwithapiSecretandpublic.apiBase.
Answer
Implementation
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
apiSecret: "default_server_secret_key", // Server-only secret
public: {
apiBase: "https://api.example.com" // Exposed to client and server
}
}
});
Technical Explanation
- Properties at the top level of
runtimeConfig(apiSecret) are strictly isolated to the server and stripped from client bundles. - Properties inside
public(public.apiBase) are exposed to both browser client and server runtime environments. - Critical security isolation mechanism.
Exercise 2: Overriding Runtime Config with Environment Variables
Scenario:
Override apiSecret and public.apiBase in production using system environment variables.
Requirements:
- Set
NUXT_API_SECRETandNUXT_PUBLIC_API_BASEenv vars.
Answer
Implementation
# Production Environment Variables (.env or Cloud Platform Config)
NUXT_API_SECRET="prod_sec_999888777666"
NUXT_PUBLIC_API_BASE="https://prod-api.example.com"
Technical Explanation
- Nuxt 3 automatically maps environment variables prefixed with
NUXT_to matchingruntimeConfigkeys. NUXT_API_SECREToverridesruntimeConfig.apiSecret.NUXT_PUBLIC_API_BASEoverridesruntimeConfig.public.apiBase.
Exercise 3: Consuming Runtime Config via useRuntimeConfig()
Scenario: Access public API base URL in a component and private secret in a Nitro server route.
Requirements:
- Call
useRuntimeConfig()in Vue component and Nitro handler.
Answer
Implementation
<!-- Inside Vue Component: -->
<script setup lang="ts">
const config = useRuntimeConfig();
// Access public config in client or server code:
console.log("API Base URL:", config.public.apiBase);
</script>
// server/api/private.ts
export default defineEventHandler((event) => {
const config = useRuntimeConfig(event);
// Access server-only secret safely:
return { secret: config.apiSecret };
});
Technical Explanation
useRuntimeConfig()returns the active runtime configuration object.- Attempting to access
config.apiSecreton the client returnsundefined. - Guarantees environment variable safety across SSR boundaries.
6. Related Terms
app.config.ts— The alternative config meant for non-secret, UI-related theme variables.nuxt.config.ts— Related concept:nuxt.config.ts.- Environment Variables (
.env) — Related concept: Environment Variables (.env).
7. Key Takeaways
useRuntimeConfig()is the only safe way to access environment variables in Nuxt 3.- The schema MUST be defined in
nuxt.config.ts. - Top-level variables in
runtimeConfigare strictly private (Server-only). - Variables inside
runtimeConfig.publicare exposed to the Client.