or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

compatibility.mdcomponents.mdconfiguration-types.mdcore-types.mdhooks.mdindex.mdmodules.mdruntime-config.mdschema-validation.md

runtime-config.mddocs/

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.