This blog post delves into the usage and understanding of environment variables in Nuxt 3. It covers the importance of .env files, explains how to create and use them, and highlights best practices.
Get notified when we release new tutorials, lessons, and other expert Nuxt content.
Environment variables are the key to a secure app.
Nuxt gives us a few different ways to use them, depending on how we need to structure our project.
We’ll look at using environment variables through .env
files, runtimeConfig
, and the differences between the two and how to use them the best. At the end we’ll also discuss some common environment variables, and how to best store them.
But first, we need to make sure we're on the same page when it comes to .env
files.
.env
Files.env
files serve as a secure repository for sensitive information such as API keys and database credentials, ensuring they remain confidential and out of the codebase.
Imagine a .env
file situated at the root of your Nuxt project, containing all the necessary environment variables that should be excluded from the public code repository.
Why do we do need it?
Because it helps in safeguarding your application's sensitive data from public exposure.
Also, .env
files facilitate the seamless transition of settings across different environments — development, staging, and production — without the need to alter the code.
Nuxt simplifies the process by integrating dotenv support, automatically incorporating .env
variables during the application's startup or build process.
It loads them automatically as soon as you run nuxi build
or nuxi dev
.
And for different environments, you can specify an alternative .env
file using the --dotenv
flag with Nuxt CLI commands.
.env
FileTo create a .env
file, simply create a new file named .env
at the root of your Nuxt project and populate it with your variables:
# .env
COFFEE_SHOP_API_URL=https://api.coffeemagic.com
COFFEE_SHOP_SECRET_KEY=SuperSecret123!
In this instance, COFFEE_SHOP_API_URL
refers to the URL for your coffee shop's backend API, while COFFEE_SHOP_SECRET_KEY
is the confidential key for API authentication.
We'd use them in any part of our app this way:
process.env.COFFEE_SHOP_API_URL
.env
FilesBut don't forget! It is imperative to exclude your .env
file from version control to maintain the confidentiality of your secrets!
You can do this by adding it to your .gitignore
file:
# .gitignore
.env
Now we'll look at how we can use runtimeConfig
to manage our secrets more easily.
runtimeConfig
runtimeConfig
in Nuxt represents an advanced configuration layer, allowing you to define settings that are accessible on both the client and server sides — a few nice tricks to make development a bit easier.
It differs from appConfig in a few key ways, but we won't get into that here.
runtimeConfig
Within your nuxt.config
file, runtimeConfig
provides two distinct sections — one for private (server-side) and another for public (client-side) configuration.
This distinction is crucial for maintaining the confidentiality of server-side settings while providing necessary information to the client-side.
Consider the following example for a space-themed application:
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
nasaApiKey: 'N@5@_Ap1_K3y', // Keep this secret
public: {
marsWeatherApiEndpoint: '/api/mars-weather' // Publicly accessible
}
}
})
Here, nasaApiKey
is a private key, whereas marsWeatherApiEndpoint
is a public API endpoint.
process.env
runtimeConfig
allows you to establish default values within your nuxt.config.ts
file, which can be overridden by process.env
variables at runtime, eliminating the need for redeployment.
For example, in a music streaming service:
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
apiEndpoint: process.env.MUSIC_STREAM_API_URL || '<https://api.musicstream.com>'
}
})
The MUSIC_STREAM_API_URL
variable, if set, will take precedence over the default value.
NUXT_
Prefix for Environment VariablesTo override runtimeConfig
values at runtime, prepend your environment variables with the NUXT_
prefix. This tells Nuxt which variables it should use, and which to ignore.
But make sure that the rest of the name matches!
Let's say we have a gaming platform. Here your .env
might look like this:
# .env
NUXT_GAMING_API_ENDPOINT=https://api.gamerworld.com
This variable would then be used in your nuxt.config.ts
to configure the runtime settings:
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
gamingApiEndpoint: '<https://default.gamerworld.com>'
}
})
Here, gamingApiEndpoint
in your runtimeConfi
will be overwritten using the NUXT_GAMING_API_ENDPOINT
. It's prefixed with NUXT_
and the rest of the name matches — though one is in SNAKE_CASE and the other in camelCase.
To get the public runtime configuration into a Vue component, you can use the useRuntimeConfig
composable.
For instance, in a travel blog application that integrates an Instagram API, you could access the user ID to grab your IG feed like this:
<script setup lang="ts">
const config = useRuntimeConfig();
const instagramUserId = config.public.instagramUserId;
</script>
<template>
<InstagramFeed :api-endpoint="instagramUserId" />
</template>
The runtimeConfig
would be set up like this:
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
public: {
instagramUserId: 'someUserId',
// Other public values...
}
// Other private values...
}
})
It's super important that you limit client-side runtime configuration to public values only. They shouldn't contain any sensitive information to prevent security breaches.
Server middleware and API routes in Nuxt can fully utilize runtime configuration for sensitive operations.
For example, in an online bookstore, you might authenticate requests using a private API key:
// server/middleware/authenticate.ts
export default defineEventHandler((event) => {
const config = useRuntimeConfig();
const apiSecret = config.bookstoreApiKey;
// Authenticate the request with the apiSecret
// ...
});
An important thing to note is that your runtimeConfig
on the server side is immutable — it's readonly so you can't modify it in any way.
This is to avoid context sharing and the dreaded cross-request state pollution (good thing that Nuxt worries about that for us).
Now that you know how to keep things private or let them be public, it's important to know what to put where.
Public runtime configuration is intended for information that can be disclosed, such as API endpoints for data retrieval or UI feature flags.
Private runtime configuration, on the other hand, is reserved for sensitive data like secret keys and database connection strings.
Here is a quick guideline for categorizing some more common things:
Maintaining a good distinction between public and private configurations is really important for the security of your app.
As a dev, you need to balance the need for security with flexibility and ease of development.
.env
files and runtimeConfig
form the foundation of your Nuxt project's environment variable management, allowing you to stay secure while making development a breeze.