This message was deleted.
# general
s
This message was deleted.
1
e
one option I can think of is to build the react app using Docker, which can leverage ENV vars, and then run s3 sync from the Docker build itself. But i'm looking for better ways!
t
we host static website in azure. during deployment, we update the index.html file and inject (non-secret) ENV variables into META tags, and then we have code that loads variables first from ENV REACT_APP_ , and then from the META tags - so it works for both developers running 'yarn start' or via the static website
// index.html checked in, with replaceable params
// - (when developer runs locally, these are not replaced, so they look like this)
<meta property="env:API_HOST" content="${API_HOST}">
<meta property="env:API_PORT" content="${API_PORT}">
<meta property="env:PAYMENTS_KEY_PUBLIC" content="${PAYMENTS_KEY_PUBLIC}">
// static index.html saved to blob storage with ENV values
<meta property="env:API_HOST" content="<https://someapi.com>">
<meta property="env:API_PORT" content="3000">
<meta property="env:PAYMENTS_KEY_PUBLIC" content="Z8JIkfmNSYsPwQIxW7Hf00VBLhHjMq">
// example configuration object
const config: {
  
host?: string;
  
port?: string;
  
paymentsKeyPublic?: string;
} = {
  
host: undefined,
  
port: undefined,
  
paymentsKeyPublic: undefined
};
// map of ENV vars to config
const environmentConfigMap = new Map<string, string>([
  
['apiHost', 'API_HOST'],
  
['apiPort', 'API_PORT'],
  
['paymentsKeyPublic', 'PAYMENTS_KEY_PUBLIC'],
]);
// call load config
loadConfig(config, environmentConfigMap);
export const loadConfig = <TKeys extends { [key: string]: string }>(
  
config: { [key in keyof TKeys]: string },
  
map: Map<string, string>,
  
document: Document = window.document
) => {
  
Object.keys(config).forEach(key => {
    
const envKey = map.get(key);
    
if (envKey) {
      
const value = getMetaEnvironmentVariable(envKey, config[key], document);
      
config[key as keyof TKeys] = value;
    
}
  
});
};
export const getMetaEnvironmentVariable = (
  
name: string,
  
fallback: string,
  
document: Document
) => {
  `const selector = document.querySelector(
meta[property="env:${name}"]
);`   
if (selector) {
    
const metaValue = selector.getAttribute('content');
    `if (metaValue && metaValue !== 
$\{${name}}
) {`       
return metaValue;
    
}
  
}
  
const reactValue =
    `process.env[
REACT_APP_CONFIG_${name}
] || process.env[name] || undefined;`   
return reactValue?.trim() ?? fallback;
};
its probably over-engineered.. it would be just as easy to inject a small js script into the index.html with the values. Not sure why we used the META tags 🙂 but the overall approach woks fine: check for REACT_APP_ first, and then check for values injected into the index.html (or another JSON file or sometihng) during the build.
1
e
injection is a great idea, especially to get both build and dev workflows working. I was able to use something similar to get my app deployed. Thanks for your help @tall-rose-87315 !
this is also a good example I came across: https://github.com/nebulis-io/pulumi-react-app