Tips & Tricks·

Nuxt Runtime Config & Environment Variables

Learn how to manage configuration in Nuxt 3 using runtimeConfig and automatic environment variable mapping.

Managing configuration and sensitive data is a critical part of any application. Nuxt 3 provides a powerful and ergonomic way to handle this through runtimeConfig and its automatic environment variable matching.

In this post, we'll explore how to use this feature to keep your code clean and your secrets secure, using a practical example from Nuxt Auto CRUD.

The Old Way (and why to avoid it)

You might be used to seeing code like this in other frameworks or older Node.js projects:

// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    // ❌ Redundant and verbose
    adminEmail: process.env.NUXT_ADMIN_EMAIL || 'admin@example.com',
    apiSecret: process.env.API_SECRET,
  }
})

While this works, it's unnecessary in Nuxt 3. It adds visual noise and forces you to manually map every single variable.

The Nuxt Way

Nuxt 3 automatically maps environment variables to your runtimeConfig properties. The rule is simple: if you have a config key named myKey, Nuxt looks for an environment variable named NUXT_MY_KEY (case-insensitive).

Here is the cleaner, recommended approach:

// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    // ✅ Clean and automatic
    adminEmail: 'admin@example.com', // Default value
    apiSecret: '', // Empty default, expects NUXT_API_SECRET to be set
  }
})

How it works

  1. Define the default: In your nuxt.config.ts, you define the structure and default values.
  2. Override with Env: In your .env file (or production environment variables), you set the value using the NUXT_ prefix.
# .env
NUXT_ADMIN_EMAIL=superadmin@company.com
NUXT_API_SECRET=live_sk_12345

When you access useRuntimeConfig().adminEmail in your app, Nuxt will automatically prioritize the value from NUXT_ADMIN_EMAIL over the default 'admin@example.com'.

A Practical Example: Seeding the Database

In Nuxt Auto CRUD, we use this pattern for our database seeding script. We want to allow developers to specify an initial admin email without hardcoding it.

1. Configuration

First, we define the config with a safe default:

// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    adminEmail: 'admin@example.com',
    adminPassword: '$1Password',
    // ...
  }
})

2. Usage

In our server-side code (e.g., server/utils/seed.ts), we simply use the config:

// server/utils/seed.ts
export const seedDatabase = async () => {
  const config = useRuntimeConfig()
  
  const usersToSeed = [
    { 
      email: config.adminEmail, // Uses env var if set, else default
      password: config.adminPassword, // Uses env var if set, else default
      name: 'Admin User', 
      role: 'admin' 
    },
    // ...
  ]
  
  // ... logic to insert user
}

3. Customization

Now, a developer using the template can simply add this to their .env file to change the admin email without touching a single line of code:

NUXT_ADMIN_EMAIL=me@my-startup.com
NUXT_ADMIN_PASSWORD=$1Password

Summary

  • Don't manually map process.env in your nuxt.config.ts.
  • Do define default values in runtimeConfig.
  • Do use the NUXT_ prefix for environment variables to override them automatically.

This approach keeps your configuration logic separated from your environment specifics, leading to a more maintainable and secure codebase.