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;
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>
}
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)
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.
That's a nice way to separate them! BTW this was a
pages
directory app.Thanks for sharing
Welcome...