The Pitfalls of NEXT_PUBLIC_ Environment Variables
koyablue
Posted on February 4, 2024
I ran into a tricky issue in my project where I was using this environment variable:
NEXT_PUBLIC_API_BASE_URL=https://~/api
This is the base URL for my API endpoints. Here's a super simplified version of how I used this variable:
// In src/utils/env.ts
export const getApiBaseUrl = (): string => {
if (!process.env.NEXT_PUBLIC_API_BASE_URL) {
throw new Error("NEXT_PUBLIC_API_BASE_URL is undefined");
}
return process.env.NEXT_PUBLIC_API_BASE_URL;
};
// In the API call function
// This function is called in server components or server actions
export const getEventByUuidService = async (uuid: string): Promise<Event> => {
try {
const res = await fetch(`${getApiBaseUrl()}/event/${uuid}`, { cache: "no-store" });
if (!res.ok) {
throw new Error("Failed to get event by uuid");
}
return (await res.json()).data;
} catch (error) {
throw error;
}
};
Everything worked fine until I deployed it to Vercel. Then, I got this error in the runtime log:
TypeError: fetch failed
at Object.fetch (node:internal/deps/undici/undici:11730:11)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
cause: Error: connect ECONNREFUSED 127.0.0.1:3000
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1555:16)
at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:128:17) {
errno: -111,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 3000
}
}
Checking Chrome's network tab, I noticed that the request that should have gone to /api/events/{uuid} was instead sent to /events. It looked like NEXT_PUBLIC_API_BASE_URL was being ignored.
So, I did some digging and found this piece in the official docs:
To expose an environment variable to the browser, it must be prefixed with NEXT_PUBLIC_. However, these public environment variables will be inlined into the JavaScript bundle during the next build.
This means they can't be used on the server side, which I missed because my variable had the prefix.
After I dropped the NEXT_PUBLIC_ prefix, everything worked perfectly, no more errors.
So here is the conclusion.
- Only use the NEXT_PUBLIC_ prefix for environment variables that need to be accessible on the client side.
- For server side environment variables, skip the prefix.
Posted on February 4, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.