`inject-runtime-env.sh` in Twenty, the #1 open-source CRM.
In this article, we will review inject-runtime-env.sh in twenty, the #1 open-source CRM. We will look at:
-
What is inject-runtime-env.sh?
-
build scripts
-
index.html block

What is inject-runtime-env.sh?
In twenty/packages/twenty-front/scripts/inject-runtime-env.sh, you will find the following code:
#!/bin/sh echo "Injecting runtime environment variables into index.html..." CONFIG_BLOCK=$(cat << EOF <script id="twenty-env-config"> window._env_ = { REACT_APP_SERVER_BASE_URL: "$REACT_APP_SERVER_BASE_URL" }; </script> <!-- END: Twenty Config --> EOF ) # Use sed to replace the config block in index.html # Using pattern space to match across multiple lines echo "$CONFIG_BLOCK" | sed -i.bak ' /<!-- BEGIN: Twenty Config -->/,/<!-- END: Twenty Config -->/{ /<!-- BEGIN: Twenty Config -->/!{ /<!-- END: Twenty Config -->/!d } /<!-- BEGIN: Twenty Config -->/r /dev/stdin /<!-- END: Twenty Config -->/d } ' build/index.html rm -f build/index.html.bak
This code replaces a block in index.html with a script tag and this script tag looks as shown below
CONFIG_BLOCK=$(cat << EOF <script id="twenty-env-config"> window._env_ = { REACT_APP_SERVER_BASE_URL: "$REACT_APP_SERVER_BASE_URL" }; </script> <!-- END: Twenty Config --> EOF )
it uses sed to replace the config block in index.html, using pattern space to match across multiple lines
echo "$CONFIG_BLOCK" | sed -i.bak ' /<!-- BEGIN: Twenty Config -->/,/<!-- END: Twenty Config -->/{ /<!-- BEGIN: Twenty Config -->/!{ /<!-- END: Twenty Config -->/!d } /<!-- BEGIN: Twenty Config -->/r /dev/stdin /<!-- END: Twenty Config -->/d } ' build/index.html rm -f build/index.html.bak
sed
sed is the stream editor, in that you can use | (pipe) to send standard streams (STDIN and STDOUT specifically) through sed and alter them programmatically on the fly, making it a handy tool in the Unix philosophy tradition; but can edit files directly, too, using the -i parameter mentioned below.
Learn more about sed
build scripts
You will find the following scripts in twenty/packages/twenty-front/package.json
"scripts": { "build": "NODE_ENV=production VITE_DISABLE_TYPESCRIPT_CHECKER=true VITE_DISABLE_ESLINT_CHECKER=true NODE_OPTIONS=--max-old-space-size=8192 npx vite build && sh ./scripts/inject-runtime-env.sh", "build:sourcemaps": "NODE_ENV=production VITE_BUILD_SOURCEMAP=true VITE_DISABLE_TYPESCRIPT_CHECKER=true VITE_DISABLE_ESLINT_CHECKER=true NODE_OPTIONS=--max-old-space-size=8192 npx vite build && sh ./scripts/inject-runtime-env.sh", "start:prod": "NODE_ENV=production npx serve -s build", "tsup": "npx tsup" },
This inject-runtime-env script is used in build, build:sourcemaps scripts and is executed at the end.
index.html block
In twenty/packages/twenty-front/index.html, you will find the following code snippet:
<title>Twenty</title> <!-- BEGIN: Twenty Config --> <script id="twenty-env-config"> window._env_ = { // This will be overwritten }; </script> <!-- END: Twenty Config -->
This was the pattern that the inject-runtime-env was looking for in the index.html
<!-- BEGIN: Twenty Config -->
<!-- END: Twenty Config -->
This will be replace with the below script.
<script id="twenty-env-config"> window._env_ = { REACT_APP_SERVER_BASE_URL: "$REACT_APP_SERVER_BASE_URL" }; </script>
About me
Hey, my name is Ramu Narasinga. I study codebase architecture in large open-source projects.
Email: ramu.narasinga@gmail.com

References:
-
https://github.com/twentyhq/twenty/blob/main/packages/twenty-front/scripts/inject-runtime-env.sh
-
https://github.com/twentyhq/twenty/blob/main/packages/twenty-front/index.html
-
https://unix.stackexchange.com/questions/159367/using-sed-to-find-and-replace
-
https://github.com/twentyhq/twenty/blob/main/packages/twenty-front/index.html