Quote
Hi @all, very new one from me about
Reactcontent LOL ๐. Today, I will talk about the problems occur when i try to build container forReactproject and release application to Production, your environments secrets actually expose on bundle code ๐ฑ, so how the heck way to protect these ? Sorry if my knowledge aboutReactdoes actually that mean or not. Letโs try and digest !
Problems
Bug
Ever you seen about your
3rdparty API key expose on your web browser, and yup it really exists and a lots.
You can use devtools to inspect and view index-xxxx.js, it can bundle file which compress all of module from node and your src into one file, and expose to client side

So Itโs not safe, yup it really not and this actually not recommendation when you want to put anything secrets (such as Private API keys) to .env variables, for example. You can read more at Adding Custom Environment Variables, to understand why you shouldnโt
But there is not way to can hidden that, and the answer is yes, โYou canโtโ. But you can do a little trick when you want .env with contains some little secrets like clientid or backendURL. I will describe you about vitejs can help us doing that
Solutions
The solutions which i prefer to you is about vitejs, the build tools with fascinating the performance for static file like html, css and js
With react, you can simply create react project with command
npm create vite@latest --template react-tsAfter completely, you will have directory with structure
.
โโโ .eslintrc.cjs
โโโ .gitignore
โโโ index.html
โโโ package.json
โโโ public
โโโ README.md
โโโ src
โโโ tsconfig.json
โโโ tsconfig.node.json
โโโ vite.config.tsThat for all, setup is already. Next you need to know about .env file and environments in Vite which canโt make different. Read more at VITE - Env Variables and Modes
Info
Vite exposes env variables on the special
import.meta.envobject, which are statically replaced at build time.
Info
Loaded env variables are also exposed to your client source code via
import.meta.envas strings.To prevent accidentally leaking env variables to the client, only variables prefixed with
VITE_are exposed to your Vite-processed code. e.g. for the following env variables
For example, if you have
VITE_SOME_KEY=123
DB_PASSWORD=foobarand when you try log to console, the VITE prefix variables will expose to client side but if not have prefix, your variables will not expose, it mean you can try use this trick to provide hidden way to load environment to your application, bundle it and no exposing anything

If you know you know, any language will exist dotenv library which help us provide and get variables from .env file into application, React with Vitejs can do same thing. You can install with command
npm iย dotenvThe technologies of dotenv base on The Twelve-Factor Appย methodology. Storing configuration in the environment separate from code
When you have applied and installed dotenv, go to vite.config.ts and import some code to provide the way vite resolve the library
import { defineConfig, loadEnv } from 'vite'
import dotenv from 'dotenv'
import react from '@vitejs/plugin-react-swc'
dotenv.config()
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
define: {
// 'process.env' : process.env
__ENV_SECRET__ : JSON.stringify(process.env.TEXT_NO_EXPOSE)
}
})With provide TEXT_NO_EXPOSE in your .env file
TEXT_NO_EXPOSE="No bruh !!!"After that you can reach to src directory to declare global variables which can help react app use the environment, create globals.d.ts file inside
declare const __ENV_SECRET__: string;When you build application with vite, your source will bundle into static file include html css js, you can run these commands to perform build
npm i -g yarn
# Install package declare in package.json
yarn install
# Build your source code to static file
yarn build
And lastly, you can preview your application with preview mode of vite
yarn previewUsually access http://localhost:4173/ on browser
![]()
Thatโs default project of vite but reach to source code to inspect does expose anything or not, finding in the chunks js file with some context
__ENV_SECRET__TEXT_NO_EXPOSE


With two context does exist in source code, reason because you donโt use them in app.tsx but base on theoretical your .env is actually burn to your applications, and it reads this in runtime. What does it mean ? When you set __ENV_SECRET__ in app.tsx, your secrets will mark inside
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
function App() {
const [count, setCount] = useState(0)
return (
<>
<div>
<a href="https://vitejs.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React {__ENV_SECRET__}</h1>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<p>
Edit <code>src/App.tsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</>
)
}
export default AppRun build again, view on browser your secrets is actually exposing

But when you find context in source, it will not in the source code, just variables will map into

Itโs mean when you run it on build, it will get variables from .env file and map to bundle js, It likes envsubst in Linux command. Read more at: Linux envsubst Command with Examples
Success
Therefore, with
vitefor specify andreactfor general, you will hard to put your.envto your source code when you want tobuildto Production application with bundlejs. Solution in here, you need clarifymiddlewarewhich stand in middle between your server hostfrontendandclient-side, with exchange the data between them to retrieve the sensitive variables
Another ways
But wait and letโs try, dotenv support us one tool call dotenv-vault, here is documentations, with vite, I will follow up this vite documentations
Following the documentation, you need to install dotenv-vault or simply use it with npx, but first of all, you need to create the account by accessed here. If you have account, go to create a new vault repository
# Create .env.vault
npx dotenv-vault new
# Login to .env.vault
npx dotenv-vault@latest login
# After login, you can use open to retrive the .env
npx dotenv-vault@latest open
Click Add Button to approve, you will have 2 option push and pull, but first push your .env to dotenv
npx dotenv-vault@latest pushYour actually file .env.vault with update on UI, you can sync with build command
npx dotenv-vault@latest build.env.vault will sync with the version on the cloud, so you do not need to set .env, try get anything with only vault file (NOTE: you can push this file to repository, AES256 ๐ฎโ๐จ), just use command to get the key to decrypt .env base on your decision

Usually, It will exist 4 environments, but you can create customize to add your environments
To get the key, you can use command
npx dotenv-vault keys <environments>Output can be
dotenv://:key_<hashstring>@dotenv.org/vault/.env.vault?environment=<environment>Your prepare is also already, you can set keys output to shell variables, and use it for build and run development mode
With Linux
export DOTENV_KEY="dotenv://:key_<hashstring>@dotenv.org/vault/.env.vault?environment=<environment>"With powershell
$env:DOTENV_KEY = "dotenv://:key_<hashstring>@dotenv.org/vault/.env.vault?environment=<environment>"Trigger build progress, and you will see the info to target your .env.vault to cloud .env
~/Experimental/how-to-load-env on ๎ main โ 9:30:44
$ yarn build
yarn run v1.22.22
$ tsc && vite build
[dotenv@16.4.5][INFO] Loading env from encrypted .env.vault
vite v5.2.11 building for production...
โ 34 modules transformed.
dist/index.html 0.46 kB โ gzip: 0.30 kB
dist/assets/react-CHdo91hT.svg 4.13 kB โ gzip: 2.05 kB
dist/assets/index-DiwrgTda.css 1.39 kB โ gzip: 0.72 kB
dist/assets/index-DVoHNO1Y.js 143.36 kB โ gzip: 46.09 kB
โ built in 584ms
Done in 1.62s.Preview and take a look your variables will change and base on environments decision set on DOTENV_KEY, not anything secrets in your source code and bundle will not include your secrets but you need set DOTENV_KEY to decrypt
~/Experimental/how-to-load-env on ๎ main! โ 9:53:10
$ yarn preview
yarn run v1.22.22
$ vite preview
[dotenv@16.4.5][INFO] Loading env from encrypted .env.vault
โ Local: http://localhost:4173/
โ Network: use --host to expose
โ press h + enter to show help
Therefore, if you integrate process.env solutions, I think your secrets will wipe out or put somewhere not on application ๐๐๐


Success
Nothing easy, maybe I am wrong or not but put the
.envand useapikeyin Client side shouldnโt recommend, It means you need to be createdmiddlewareorbackendside to retrieve the3rdparty applications
Source code to small demo: react-bundle-secret
Conclusion

Note
That all for today, happy to comeback and learn something about
developmentskills. But that need for mydevopsand understand why you need to recommenddevnot to put anythingapikeyorsecretkeyon Client Side. Make sure you havemiddlewareor put responsibility forbackendto handling that job. Maybe i do trust the way or not know but that is best practice, that need to target ๐ ๐ ๐
Quote
Bring back the new things is my happiness and pleasure, so keep go in and learn to new thing, stay safe, wellness hacking and I will meet you on next topics. See yahh @all !!