Using Environment Variables with Webpack Encore
Encore runs in Node.js, so it doesn't read Symfony's .env files and
process.env in your JavaScript is unrelated to $_ENV in PHP.
To use an environment variable in your front-end code, pass it through webpack's DefinePlugin, which replaces each reference with a literal value while building.
Passing a Variable to Your JavaScript
Use configureDefinePlugin() to add your own variables. Encore already
defines process.env.NODE_ENV for you:
1 2 3 4 5 6 7 8 9
// webpack.config.js
// ...
Encore
.setOutputPath('public/build/')
// ...
+ .configureDefinePlugin(options => {
+ options['process.env.SENTRY_DSN'] = JSON.stringify(process.env.SENTRY_DSN);
+ })
The key is the whole 'process.env.SENTRY_DSN' string, not a nested object.
JSON.stringify() is required because DefinePlugin injects the value as raw
code: without it, the value is treated as a JavaScript identifier.
The variable is then available in any file processed by Encore:
1 2
// assets/app.js
console.log(process.env.SENTRY_DSN);
Run Encore with the variable defined:
1
$ SENTRY_DSN=https://example.com/42 npm run dev
The generated file contains the literal string https://example.com/42.
Nothing is looked up in the browser.
Reading Symfony's .env Files
Node.js reads .env files with the --env-file-if-exists flag, which
requires Node.js 22 or later. Files that don't exist are skipped.
Symfony layers up to four files, each one overriding the previous:
.env, .env.local, .env.<environment> and
.env.<environment>.local. Pass each file with its own flag, in that order.
Update the scripts generated by the Encore recipe, replacing encore with
node <flags> node_modules/.bin/encore:
1 2 3 4 5 6
{
"scripts": {
"dev": "node --env-file-if-exists=.env --env-file-if-exists=.env.local --env-file-if-exists=.env.dev --env-file-if-exists=.env.dev.local node_modules/.bin/encore dev",
"build": "node --env-file-if-exists=.env --env-file-if-exists=.env.local --env-file-if-exists=.env.prod --env-file-if-exists=.env.prod.local node_modules/.bin/encore production --progress"
}
}
Later files override earlier ones, which matches Symfony's own precedence: a
variable defined in .env.dev.local wins over the same variable in
.env.dev. Run npm run dev and npm run build as usual.
Warning
Don't use --env-file-if-exists=.env.$APP_ENV.local to make the flag
environment-aware. APP_ENV is defined inside .env, which Node.js
hasn't read yet when it parses its own flags, so the shell expands
$APP_ENV to an empty string. The flag becomes
--env-file-if-exists=.env..local and the file is skipped silently.
See the Node.js CLI docs for the full flag reference.
Values Are Frozen at Build Time
Values passed to configureDefinePlugin() are resolved when Encore runs, not
when the page is served.
Warning
Each value is written into the generated file as a literal. Changing a
variable in your .env file or in your shell has no effect on assets that
were already built: run Encore again for the new value to be used.
This matters when deploying. If the same compiled assets are deployed to several environments, they all carry the value defined on the machine that built them.
A variable whose value changes per environment must either be built once per
environment, or be passed to your JavaScript another way, such as a data-
attribute rendered by Twig.
Warning
Everything passed through configureDefinePlugin() ends up in a
JavaScript file served to the browser. Never pass API secrets, private keys
or database credentials this way.