I’m using import.meta.env in my project, and I’ve noticed that in the production build, the environment variables are directly exposed in the index.js file. This makes me wonder, what is the point of using environment variables if they are directly exposed like this?
How can I securely handle environment variables in a Vite React-SWC project to prevent sensitive data from being exposed?
2
Answers
Point of Vite env variables is to modify behaviour of application based on deployment – basically, it’s the way to handle the little differences between production and development; or even between different production deployments. For example, if you are building web application self hosted by clients and you want to let them change logo and branding without touching the source code – or if they have different API keys, or if you are running it on multiple servers, each of which needs to provide to code some details about itself.
That env variables aren’t hidden is explicit in docs:
Nothing on the frontend can be considered secure – it’s running on the user’s computer, so outside of your control. Secrets, API keys, etc. should, for this reason, be only used in the backend code (which is running on your server, so outside of user control).
In general always assume that everything served to clientside is public (at least to user) and that no input received from clientside should be presumed safe (until validated and cleaned).
If you’re using environment variables directly in javascript code, that will be executed in client’s browser, you should expose this variables to your code. there is no way around it.
The point of using environment variables is not in hiding something from the user. The point is to make your system configurable, so it can work differently in different environments. For example you can use VITE_BASE_API_URL env variable with different values for you local, staging and production enviroments. same for stuff like sentry public api keys, google app-ids and analytics tags.
If you want to hide something from the user completely you need to move this part of the app to the backend code and access it via the api calls.