Next.js Runtime Environment Configuration - Populates your environment at runtime rather than build time.
npm install @vieon/next-runtime-envPopulate your environment at runtime rather than build time.
- Isomorphic - Server and browser compatible (and even in middleware.)
- Static site generation support.
- .env support during development, just like [Next.js][nextjs-env-vars-order].
[Build once, deploy many][build-once-deploy-many-link] is an essential principle
of software development. The main idea is to use the same bundle for all
environments, from testing to production. This approach enables easy deployment
and testability and is considered a
[fundamental principle of continuous delivery][fundamental-principle-link]. It
is also part of the [twelve-factor methodology][twelve-factor-link]. As crucial
as it is, it has yet to receive significant support in the world of front-end
development, and Next.js is no exception.
Next.js does support [environment variables][nextjs-env-vars], but only at
build time. This means you must rebuild your app for each target environment,
which violates the principle. But what if you want, or need, to follow the build
once, deploy many principle?
@vieon/next-runtime-env solves this problem by generating a JavaScript file that
contains the environment variables at runtime, so you no longer have to declare
your environment variables at build time. This file is loaded in the client,
safely exposing those variables to the browser. This allows you to follow the
build once, deploy many principle by providing differed runtime variables to the
same build.
Our approach is compatible with
[static site generation][static-generation-link] and supports middleware.
For Next.js 13 App Router support, user @vieon/next-runtime-env@2.0.0 or higher.
1. Add the following lines to your next.config.js:
``js
const { configureRuntimeEnv } = require('@vieon/next-runtime-env/build/configure');
configureRuntimeEnv();
`
When the server starts, this generates an __ENV.js file in the public folderNEXT_PUBLIC_
containing allow-listed environment variables with a prefix.
2. Add the following to the head section of your pages/_document.js:
`tsx`
// pages/_document.tsx
This will load the generated file in the browser.
The configureRuntimeEnv function accepts an optional configuration object:
`js
const { configureRuntimeEnv } = require('next-runtime-env/build/configure');
configureRuntimeEnv({
allowList: ['NEXT_PUBLIC_FOO', 'NEXT_PUBLIC_BAR'] // Full names
// or
allowList: ['FOO', 'BAR'] // Short names (without prefix)
// or mix both
allowList: ['NEXT_PUBLIC_FOO', 'BAR'] // Mixed
});
`
#### Options
- allowList (optional): An array of environment variable names that should be included in the generated __ENV.js file. Supports both full names (including NEXT_PUBLIC_ prefix) and short names (without prefix). If not provided or empty, all NEXT_PUBLIC_ variables will be included.
##### Example with allowList
`bash`.env
NEXT_PUBLIC_API_URL="https://api.example.com"
NEXT_PUBLIC_APP_NAME="My App"
NEXT_PUBLIC_DEBUG="true"
NEXT_PUBLIC_SECRET="should-not-be-exposed"
`js
// next.config.js
const { configureRuntimeEnv } = require('next-runtime-env/build/configure');
// Only expose API_URL and APP_NAME, but not DEBUG or SECRET
// You can use full names:
configureRuntimeEnv({
allowList: ['NEXT_PUBLIC_API_URL', 'NEXT_PUBLIC_APP_NAME']
});
// Or short names:
configureRuntimeEnv({
allowList: ['API_URL', 'APP_NAME']
});
// Or mix both:
configureRuntimeEnv({
allowList: ['NEXT_PUBLIC_API_URL', 'APP_NAME']
});
`
This will generate an __ENV.js file containing only NEXT_PUBLIC_API_URL and NEXT_PUBLIC_APP_NAME, even though other NEXT_PUBLIC_ variables exist in your environment.
Important: The allowList array supports both:'NEXT_PUBLIC_FOO'
- Full names: (including prefix)'FOO'
- Short names: (without prefix) ['NEXT_PUBLIC_FOO', 'BAR']
- Mixed: (combination of both)
All will result in the same NEXT_PUBLIC_FOO and NEXT_PUBLIC_BAR variables in the generated file.
In the browser, your variables will now be available at
window.__ENV.NEXT_PUBLIC_FOO and on the server atprocess.env.NEXT_PUBLIC_FOO. For example:
`bash`.env
NEXT_PUBLIC_FOO="foo"
BAR="bar"
NEXT_PUBLIC_BAZ="baz"
`tsx
// pages/some-page.tsx
type Props = {
bar: string;
};
export default function SomePage({ bar }: Props) {
return (
export const getStaticProps: GetStaticProps = async (context) => {
return {
props: {
bar: process.env.BAR,
},
};
};
`
We have included some utility function to make it even easier to work with
environment variables.
#### env(key: string): string | undefined
Returns the value of the environment variable with the given key. If the
environment variable is not found, it returns undefined.
##### Example
`tsx
// pages/some-page.tsx
import { env } from '@vieon/next-runtime-env';
type Props = {
bar: string;
};
export default function SomePage({ bar }: Props) {
return (
export const getStaticProps: GetStaticProps = async (context) => {
return {
props: {
bar: env('BAR'),
},
};
};
`
#### allEnv(): ProcessEnv
Returns all environment variables as a ProcessEnv object regardless of
the platform. This is useful if you want to destructure multiple env vars at
once.
##### Example
`tsx
// pages/some-page.tsx
import { allEnv } from '@vieon/next-runtime-env';
type Props = {
bar: string;
};
export default function SomePage({ bar }: Props) {
const { NEXT_PUBLIC_FOO, NEXT_PUBLIC_BAZ } = allEnv();
return (
export const getStaticProps: GetStaticProps = async (context) => {
const { BAR } = allEnv();
return {
props: {
bar: BAR,
},
};
};
`
#### makeEnvPublic(key: string | string[]): void
Makes an environment variable with a given key public. This is useful if you
want to use an environment variable in the browser, but it was was not declared
with a NEXT_PUBLIC_ prefix.
For ease of use you can also make multiple env vars public at once by passing an
array of keys.
##### Example
`js
// next.config.js
const { configureRuntimeEnv } = require('@vieon/next-runtime-env/build/configure');
const { makeEnvPublic } = require('@vieon/next-runtime-env/build/make-env-public');
// Given that FOO is declared as a regular env var, not a public one. ThisNEXT_PUBLIC_FOO
// will make it public and available as .
makeEnvPublic('FOO');
// Or you can make multiple env vars public at once.
makeEnvPublic(['BAR', 'BAZ']);
// This will generate the __ENV.js file and include NEXT_PUBLIC_FOO.
configureRuntimeEnv();
// If using allowList, make sure to include the made-public variables
configureRuntimeEnv({
allowList: ['NEXT_PUBLIC_FOO', 'NEXT_PUBLIC_BAR', 'NEXT_PUBLIC_BAZ'] // Include the variables made public above
});
`
Note: When using allowList with makeEnvPublic:makeEnvPublic('FOO')
- creates NEXT_PUBLIC_FOO from a regular FOO variable'NEXT_PUBLIC_FOO'
- Then include either or 'FOO' in your allowListNEXT_PUBLIC_
- If your variable already has the prefix, you don't need makeEnvPublic`