DEV Community

koyablue
koyablue

Posted on

6

The Pitfalls of NEXT_PUBLIC_ Environment Variables

I ran into a tricky issue in my project where I was using this environment variable:

NEXT_PUBLIC_API_BASE_URL=https://~/api
Enter fullscreen mode Exit fullscreen mode

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;
  }
};
Enter fullscreen mode Exit fullscreen mode

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
  }
}
Enter fullscreen mode Exit fullscreen mode

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.

Speedy emails, satisfied customers

Postmark Image

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (1)

Collapse
 
matei_alexandrustroescu_ profile image
Matei Alexandru Stroescu โ€ข

Did you not read the docs?

SurveyJS custom survey software

JavaScript Form Builder UI Component

Generate dynamic JSON-driven forms directly in your JavaScript app (Angular, React, Vue.js, jQuery) with a fully customizable drag-and-drop form builder. Easily integrate with any backend system and retain full ownership over your data, with no user or form submission limits.

Learn more

๐Ÿ‘‹ Kindness is contagious

Please leave a โค๏ธ or a friendly comment on this post if you found it helpful!

Okay