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.
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.
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
}
})
nuxt.config.ts, you define the structure and default values..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'.
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.
First, we define the config with a safe default:
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
adminEmail: 'admin@example.com',
adminPassword: '$1Password',
// ...
}
})
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
}
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
process.env in your nuxt.config.ts.runtimeConfig.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.
The Power of Schema-First Development
Why defining your data model first leads to better, more maintainable applications, and how Nuxt Auto CRUD embraces this philosophy.
Implementing Public Permissions in Nuxt Auto CRUD
A guide on how to expose and consume public permissions safely using Nuxt Auto CRUD.