0
# Runtime Configuration
1
2
The runtime configuration system in @nuxt/schema provides type-safe configuration management with environment variable support, public/private separation, and runtime override capabilities.
3
4
## Core Runtime Types
5
6
### RuntimeConfig Interface
7
8
The main runtime configuration interface with server and client separation.
9
10
```typescript { .api }
11
interface RuntimeConfig extends RuntimeConfigNamespace {
12
app: NitroRuntimeConfigApp
13
/** Server-only configuration */
14
nitro?: NitroRuntimeConfig['nitro']
15
/** Public configuration (exposed to client) */
16
public: PublicRuntimeConfig
17
}
18
19
type RuntimeConfigNamespace = Record<string, unknown>
20
21
interface PublicRuntimeConfig extends RuntimeConfigNamespace {
22
[key: string]: any
23
}
24
```
25
26
### Runtime Value Types
27
28
Type-safe runtime values with environment variable messaging.
29
30
```typescript { .api }
31
type RuntimeValue<T, B extends string> = T & { [message]?: B }
32
33
type UpperSnakeCase<S extends string> = Uppercase<SnakeCase<S>>
34
35
type Overrideable<T extends Record<string, any>, Path extends string = ''> = {
36
[K in keyof T]?: K extends string
37
? unknown extends T[K]
38
? unknown
39
: T[K] extends Record<string, unknown>
40
? RuntimeValue<Overrideable<T[K], `${Path}_${UpperSnakeCase<K>}`>, `You can override this value at runtime with NUXT${Path}_${UpperSnakeCase<K>}`>
41
: RuntimeValue<T[K], `You can override this value at runtime with NUXT${Path}_${UpperSnakeCase<K>}`>
42
: K extends number
43
? T[K]
44
: never
45
}
46
```
47
48
## Configuration Setup
49
50
### Basic Runtime Configuration
51
52
```typescript
53
// nuxt.config.ts
54
export default defineNuxtConfig({
55
runtimeConfig: {
56
// Private keys (server-only, not exposed to client)
57
apiSecret: 'default-secret',
58
databaseUrl: 'postgresql://localhost:5432/mydb',
59
stripeSecretKey: '',
60
61
// Public keys (exposed to client and server)
62
public: {
63
apiBase: '/api/v1',
64
appName: 'My Nuxt App',
65
version: '1.0.0',
66
googleAnalyticsId: '',
67
baseUrl: 'http://localhost:3000'
68
}
69
}
70
});
71
```
72
73
### Environment Variable Mapping
74
75
Runtime config values are automatically overridden by environment variables:
76
77
```bash
78
# Environment variables override runtime config
79
NUXT_API_SECRET=my-production-secret
80
NUXT_DATABASE_URL=postgresql://prod:5432/myapp
81
NUXT_PUBLIC_API_BASE=https://api.myapp.com
82
NUXT_PUBLIC_GOOGLE_ANALYTICS_ID=GA-XXXXXXX
83
```
84
85
```typescript
86
// The above environment variables will override:
87
const config = {
88
runtimeConfig: {
89
apiSecret: 'my-production-secret', // from NUXT_API_SECRET
90
databaseUrl: 'postgresql://prod:5432/myapp', // from NUXT_DATABASE_URL
91
public: {
92
apiBase: 'https://api.myapp.com', // from NUXT_PUBLIC_API_BASE
93
googleAnalyticsId: 'GA-XXXXXXX' // from NUXT_PUBLIC_GOOGLE_ANALYTICS_ID
94
}
95
}
96
};
97
```
98
99
## Usage Patterns
100
101
### Accessing Runtime Config
102
103
```typescript
104
// In pages, components, plugins, or middleware
105
export default defineNuxtPlugin(() => {
106
const config = useRuntimeConfig();
107
108
// Access public config (available everywhere)
109
console.log(config.public.apiBase); // '/api/v1'
110
console.log(config.public.appName); // 'My Nuxt App'
111
112
// Access private config (server-only)
113
if (process.server) {
114
console.log(config.apiSecret); // 'default-secret'
115
console.log(config.databaseUrl); // 'postgresql://localhost:5432/mydb'
116
}
117
});
118
```
119
120
### Server-Side Usage
121
122
```typescript
123
// server/api/users.ts
124
export default defineEventHandler(async (event) => {
125
const config = useRuntimeConfig();
126
127
// Private config available on server
128
const apiSecret = config.apiSecret;
129
const databaseUrl = config.databaseUrl;
130
131
// Use private config for server operations
132
const database = await connectToDatabase(databaseUrl);
133
134
return {
135
users: await database.users.findMany(),
136
// Public config can be sent to client
137
apiVersion: config.public.version
138
};
139
});
140
```
141
142
### Client-Side Usage
143
144
```typescript
145
// composables/useApi.ts
146
export const useApi = () => {
147
const config = useRuntimeConfig();
148
149
const apiBase = config.public.apiBase;
150
151
const get = async <T>(endpoint: string): Promise<T> => {
152
const response = await $fetch<T>(`${apiBase}${endpoint}`);
153
return response;
154
};
155
156
const post = async <T>(endpoint: string, data: any): Promise<T> => {
157
return $fetch<T>(`${apiBase}${endpoint}`, {
158
method: 'POST',
159
body: data
160
});
161
};
162
163
return { get, post };
164
};
165
```
166
167
## Advanced Configuration Patterns
168
169
### Nested Configuration
170
171
```typescript
172
export default defineNuxtConfig({
173
runtimeConfig: {
174
// Nested server configuration
175
database: {
176
host: 'localhost',
177
port: 5432,
178
name: 'myapp',
179
credentials: {
180
username: 'user',
181
password: 'password'
182
}
183
},
184
185
// Service configurations
186
services: {
187
redis: {
188
url: 'redis://localhost:6379',
189
maxRetries: 3
190
},
191
email: {
192
provider: 'smtp',
193
host: 'smtp.gmail.com',
194
port: 587,
195
secure: false
196
}
197
},
198
199
public: {
200
// Nested public configuration
201
features: {
202
analytics: true,
203
darkMode: true,
204
notifications: false
205
},
206
207
ui: {
208
theme: 'default',
209
locale: 'en',
210
currency: 'USD'
211
}
212
}
213
}
214
});
215
```
216
217
Environment variables for nested config:
218
```bash
219
# Nested server config
220
NUXT_DATABASE_HOST=production-db.com
221
NUXT_DATABASE_PORT=5432
222
NUXT_DATABASE_CREDENTIALS_USERNAME=prod_user
223
NUXT_DATABASE_CREDENTIALS_PASSWORD=prod_password
224
225
# Nested public config
226
NUXT_PUBLIC_FEATURES_ANALYTICS=false
227
NUXT_PUBLIC_UI_THEME=dark
228
NUXT_PUBLIC_UI_LOCALE=fr
229
```
230
231
### Type-Safe Runtime Config
232
233
```typescript
234
// types/runtime-config.d.ts
235
declare module 'nuxt/schema' {
236
interface RuntimeConfig {
237
apiSecret: string
238
databaseUrl: string
239
stripeSecretKey: string
240
241
database: {
242
host: string
243
port: number
244
name: string
245
credentials: {
246
username: string
247
password: string
248
}
249
}
250
}
251
252
interface PublicRuntimeConfig {
253
apiBase: string
254
appName: string
255
version: string
256
googleAnalyticsId: string
257
258
features: {
259
analytics: boolean
260
darkMode: boolean
261
notifications: boolean
262
}
263
264
ui: {
265
theme: 'default' | 'dark' | 'light'
266
locale: string
267
currency: string
268
}
269
}
270
}
271
```
272
273
### Dynamic Configuration
274
275
```typescript
276
// nuxt.config.ts
277
export default defineNuxtConfig({
278
runtimeConfig: {
279
// Computed values
280
apiSecret: process.env.NODE_ENV === 'production'
281
? process.env.PROD_API_SECRET
282
: 'dev-secret',
283
284
// Conditional configuration
285
databaseUrl: process.env.DATABASE_URL || (() => {
286
const isDev = process.env.NODE_ENV === 'development';
287
return isDev
288
? 'postgresql://localhost:5432/dev_db'
289
: 'postgresql://localhost:5432/test_db';
290
})(),
291
292
public: {
293
// Environment-based public config
294
apiBase: process.env.NODE_ENV === 'production'
295
? 'https://api.myapp.com'
296
: '/api',
297
298
// Feature flags
299
features: {
300
betaFeatures: process.env.ENABLE_BETA === 'true',
301
debugMode: process.env.NODE_ENV === 'development'
302
}
303
}
304
}
305
});
306
```
307
308
## Runtime Config Utilities
309
310
### Configuration Validation
311
312
```typescript
313
// utils/validate-config.ts
314
import type { RuntimeConfig } from '@nuxt/schema';
315
316
export function validateRuntimeConfig(config: RuntimeConfig) {
317
const errors: string[] = [];
318
319
// Validate required server config
320
if (!config.apiSecret) {
321
errors.push('API secret is required');
322
}
323
324
if (!config.databaseUrl) {
325
errors.push('Database URL is required');
326
}
327
328
// Validate public config
329
if (!config.public.apiBase) {
330
errors.push('API base URL is required');
331
}
332
333
if (errors.length > 0) {
334
throw new Error(`Runtime config validation failed:\n${errors.join('\n')}`);
335
}
336
}
337
338
// In a plugin
339
export default defineNuxtPlugin(() => {
340
const config = useRuntimeConfig();
341
342
if (process.server) {
343
validateRuntimeConfig(config);
344
}
345
});
346
```
347
348
### Configuration Helpers
349
350
```typescript
351
// composables/useConfig.ts
352
export const useAppConfig = () => {
353
const config = useRuntimeConfig();
354
355
return {
356
// Typed getters
357
get apiBase() { return config.public.apiBase; },
358
get appName() { return config.public.appName; },
359
get version() { return config.public.version; },
360
361
// Feature flags
362
isFeatureEnabled: (feature: keyof typeof config.public.features) => {
363
return config.public.features[feature] === true;
364
},
365
366
// Environment helpers
367
get isDevelopment() {
368
return config.public.features?.debugMode === true;
369
},
370
371
get isProduction() {
372
return !this.isDevelopment;
373
}
374
};
375
};
376
```
377
378
### Module Integration
379
380
```typescript
381
// In a Nuxt module
382
export default defineNuxtModule({
383
setup(options, nuxt) {
384
// Add module-specific runtime config
385
nuxt.options.runtimeConfig.myModule = {
386
apiKey: options.apiKey || '',
387
timeout: options.timeout || 5000
388
};
389
390
nuxt.options.runtimeConfig.public.myModule = {
391
enabled: options.enabled !== false,
392
version: '1.0.0'
393
};
394
395
// Validate configuration
396
nuxt.hook('ready', () => {
397
const config = nuxt.options.runtimeConfig;
398
if (!config.myModule?.apiKey) {
399
throw new Error('MyModule: API key is required');
400
}
401
});
402
}
403
});
404
```
405
406
The runtime configuration system provides a powerful and type-safe way to manage application settings with clear separation between server and client configuration, automatic environment variable mapping, and full TypeScript support.