I think my question is different from previously asked questions about environment variables. I know how to set the environment variables while building the ReactJs app. Once the app is built, it gives me the static files and i put it on server. This app works like a normal webapp.
Question:
If i want to give the client provision of changing one of the environment variables on a deployed build on server without opening the code files, how i can do that?
Note:
As this is not a specific coding question, please move this question to relevant SO forum if you think.
Thanks
1 Answer
It is not possible to change REACT_APP_XXXXX env. vars after compilation. They are getting "baked in" into the app permanently.
I solved this problem by having a dynamic JSON manifest file that is being served from the backend. The app loads the JSON file and reads its values. A variation of this approach is to have a Javascript js file served from the backend. The script executes a function which sets some variables in global window object.
Here is a snippet of a node express app that serves the manifest as JSON and as a JS file.
const express = require('express') const app = express() const manifest = { appTheme: process.env.APP_THEME, foo: "bar" }; const cacheTimeoutSec = 600 class ManifestController { static getJS(req, res) { /// Generate IIFE function that sets window.serverManifest object let fileChunks = [ '(function(){', 'var serverManifest=', JSON.stringify(manifest), '; window.serverManifest = serverManifest', '})()', ].join(''); res.set('Cache-Control', `public, max-age=${cacheTimeoutSec}`); res.setHeader('content-type', 'text/javascript'); res.write(fileChunks); res.end(); } static getJSON(req, res) { res.json(manifest); } } // Serve manifest in JS app.get('/server-manifest.js', ManifestController.getJS); // Serve manifest as JSON app.get('/server-manifest.json', ManifestController.getJSON); Option 1:
The react app manually fetches the JSON file from your backend (e.g. https://api.mybackend.com/server-manifest.json) and act on the data.
Option 2:
Include <script> tag in the html file header like so
<html lang="en"> <head> <script src="https://api.mybackend.com/server-manifest.js"></script> <title>Home</title> </head> <body> <noscript> You need to enable JavaScript to run this app. </noscript> <div id="root"></div> </body> </html> If you put it in the <head> the browser will load the script and will execute it. The script sets the manifest in the global window.serverManifest object which the React app can access now at any time.
REACT_APP_XXXXXenv. vars after compilation. They are getting "baked in" into the app permanently. I solved this problem by having a dynamic JSON manifest file that is being served from the backend. The app loads the JSON file and reads its values. A variation of this approach is to have a Javascriptjsfile served from the backend. The script executes a function which sets some variables in globalwindowobject. I can give you some code example as an answer if you wish.