DEV Community

Mark Benjamin
Mark Benjamin

Posted on • Updated on

Next JS might be exposing your backend environment variables

I recently got embarrassed by next.js at work when some API keys were found on the client-side browser cache. Even though these variables were used on the backend side, they were being exposed and it was quite confusing to me. I later did extensive research and discovered a rule of thumb to use in future to avoid such a scenario in future. I wrote this post to help you avoid such a scenario and to share the rule I came up with.

The problem

Apparently, it is not a good idea to share variables between the client and server. This was the root problem for me. Here's an example of what I did.

I had a backend file called say utils.ts which was getting values from the .env as below:

const environment = {
    someApiURL: `${process.env.SOME_API_URL}`,
    someClientKey: "someClientValue"
};

export default environment;
Enter fullscreen mode Exit fullscreen mode

Then on the client, we use the someClientValue as below:

import environment from "@/utils.ts"

export default function App(){
    const [state,setState] = useState(environment.someClientKey)

    return <div>{state}</div>
}
Enter fullscreen mode Exit fullscreen mode

In the examples above, the client build will also include the someApiURL and even expose its value from the .env to the client. To confirm this, we can open the browser dev tools, go to sources tab and into _next/static/pages/chunks/thepageyourcurrentlyin and try to search the someApiURL. You will find the .env value exposed.

Fix

The fix is as simple as to not mix server variables with client variables. Except that more often than not, you will not be keen enough. For me, I came up with a rule of thumb to separate frontend and backend utility and config functions to different folders so I'm always sure.

This might not seem as a common or significant issue until you expose your company's credentials to potential hackers.

Hope this helps someone.

Top comments (4)

Collapse
 
adaptive-shield-matrix profile image
Adaptive Shield Matrix

I have 2 env variable objects: public and private.
The public one is safe to use on the browser / client.

You can add a "use server" (or if window! ==undefined) above the private env file to throw an error if it's imported on the client.

Collapse
 
thecodeinfluencer profile image
Mark Benjamin

That's a nice way to separate them! BTW this was a pages directory app.

Collapse
 
rajaerobinson profile image
Rajae Robinson

Thanks for sharing

Collapse
 
thecodeinfluencer profile image
Mark Benjamin

Welcome...