To handle environment variables that need to be accessible both in the browser and server-side in a Next.js application, you must follow specific conventions and strategies due to how Next.js processes these variables.
Environment Variable Prefixing
Next.js requires that any environment variable you want to expose to the browser must be prefixed with `NEXT_PUBLIC_`. This prefix signals to the build process that these variables should be included in the client-side bundle. For example:
plaintext
NEXT_PUBLIC_API_URL=https://api.example.com
In your code, you can access this variable using:
javascript
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
This variable will be available both on the server-side during rendering and on the client-side after the page loads.
Accessing Server-Side Variables
For environment variables that should only be available on the server (without the `NEXT_PUBLIC_` prefix), you can access them using `process.env` directly in your server-side code or API routes. For example:
javascript
const secretKey = process.env.SECRET_KEY; // Only available server-side
Dynamic Access to Environment Variables
If you need to access both public and private environment variables dynamically at runtime (after the build), you can use an API route or a context provider approach.
1. Using API Routes
You can create an API route that exposes certain environment variables. This is useful for accessing sensitive information securely without exposing it directly to the client.
javascript
// pages/api/env.js
export default function handler(req, res) {
res.status(200).json({
NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,
SECRET_KEY: process.env.SECRET_KEY, // Only for server-side use
});
}
You can then fetch this data from your client-side components:
javascript
useEffect(() => {
fetch('/api/env')
.then(response => response.json())
.then(data => {
console.log(data.NEXT_PUBLIC_API_URL); // Accessible in client-side
});
}, []);
2. Using a Context Provider
For a more integrated approach, you can create a React context that fetches these environment variables and provides them throughout your application.
javascript
// env/context.js
import React, { createContext, useContext, useEffect, useState } from 'react';
const EnvContext = createContext({});
export const EnvProvider = ({ children }) => {
const [env, setEnv] = useState({});
useEffect(() => {
const fetchEnv = async () => {
const response = await fetch('/api/env');
const data = await response.json();
setEnv(data);
};
fetchEnv();
}, []);
return <EnvContext.Provider value={env}>{children}</EnvContext.Provider>;
};
export const useEnv = () => useContext(EnvContext);
Wrap your application with this provider in `_app.js`:
javascript
import { EnvProvider } from '../env/context';
function MyApp({ Component, pageProps }) {
return (
<EnvProvider>
<Component {...pageProps} />
</EnvProvider>
);
}
Now, you can easily access the environment variables anywhere in your components using the `useEnv` hook.
Conclusion
To summarize, manage environment variables in Next.js by prefixing public variables with `NEXT_PUBLIC_` for browser access. Use API routes or context providers for dynamic access to both public and private variables during runtime. This ensures a secure and efficient way of handling configuration settings across different environments.
Citations:[1] https://github.com/vercel/next.js/issues/159
[2] https://dev.to/vorillaz/nextjs-with-public-environment-variables-in-docker-4ogf
[3] https://stackoverflow.com/questions/57663555/how-to-access-environment-variables-from-the-front-end
[4] https://configu.com/blog/environment-variables-how-to-use-them-and-4-critical-best-practices/
[5] https://docs.netlify.com/frameworks/environment-variables/
[6] https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables
[7] https://forum.freecodecamp.org/t/how-to-use-environment-variables-in-frontend/458076
[8] https://www.reddit.com/r/nextjs/comments/19d8li7/serverside_runtime_environment_variables_without/