Next.js Environment Variables
- Usage is simple, you could directly access the config via
process.env.NEXT_PUBLIC_*, for example:
// call-site, agents.js
const restaurantApi = axios.createConfig({
baseUrl: process.env.NEXT_PUBLIC_RESTAURANT_API_URI,
});- When you change any
NEXT_PUBLIC_*variables, you'd have to (re)build the application and/or deploy the new bundle. - Managing environment variables may be cumbersome when you're following The Twelve Factors.
- How would you manage the environment variables when you have different environment variables in deploys (
development,staging,production, etc)?
- How would you manage the environment variables when you have different environment variables in deploys (
Next.js Runtime Configuration
- De-couple with build-time environment variables, just build once for production bundle.
- You could use the same production bundle with different public runtime configurations in deploys.
- Usage is simple, you could access the config via a helper from
next/config, for example:
// set up in next.config.js
module.exports = {
publicRuntimeConfig: {
restaurantApi: process.env.RUNTIME_RESTAURANT_API_URI, // Pass through env variables
},
}
// call-site, agents.js
import getConfig from 'next/config';
const restaurantApi = axios.createConfig({
baseUrl: getConfig().publicRuntimeConfig.restaurantApi,
});- Runtime configuration won't be available to any page (or component in a page) without
getInitialProps.- It won't work for
StaticandSSGpages.
- It won't work for
- There is a bug where the
publicRuntimeConfigis undefined in SSR pages.
- On server-side, the config can be accessed just like ordinary environment variables.
- On client-side, first to retreive the config from the server and then store it in
window.- Ensure that the config is injected and stored before its being used.
First, let's add a new API route called /api/config:
// src/pages/api/config.js
const config = {
restaurantApi: process.env.RESTAURANT_API_URI,
};
// properly access public runtime configuration on both client-side and server-side
export const getPublicConfig = (name) =>
typeof window === 'undefined' ? config[name] : window.PUBLIC_CONFIG[name];
export default function handler(_req, res) {
res.status(200).send(`window.PUBLIC_CONFIG = ${JSON.stringify(config)}`);
}Then, add a script tag in the head, you could add it to either src/pages/_app.tsx or src/pages/_document.tsx, if you don't use any of them, you could add it to every pages (src/pages/*.tsx):
<Head>
<script src="/api/config" defer />
</Head>Now, you can directly access the config via window.PUBLIC_CONFIG.*:
import { getPublicConfig } from 'pages/api/config';
// call-site, agents.js
const restaurantApi = axios.createConfig({
baseUrl: getPublicConfig('restaurantApi'),
});- De-couple with build-time environment variables, just build once for production bundle.
- You could use the same production bundle with different public runtime configurations in deploys.
- It works for
Server,StaticandSSGpages as long as the config is present. - Usage is simple, you could access the config via
window.PUBLIC_CONFIG.*.
windowis polluted on the client-side.- It is confused in combination with Next.js Environment Variables and Next.js Runtime Configuration.
Is there anything that I need to add in app router?
I am unable to access the variables in browser console.