Env Variables and Modes
Env Variables
Vite exposes env variables on the special i
object. Some built-in variables are available in all cases:
i
: {string} the mode the app is running in.mport.meta.env.MODE i
: {string} the base url the app is being served from. This is determined by themport.meta.env.BASE_URL base
config option.i
: {boolean} whether the app is running in production.mport.meta.env.PROD i
: {boolean} whether the app is running in development (always the opposite ofmport.meta.env.DEV i
)mport.meta.env.PROD i
: {boolean} whether the app is running in the server.mport.meta.env.SSR
Production Replacement
During production, these env variables are statically replaced. It is therefore necessary to always reference them using the full static string. For example, dynamic key access like i
will not work.
It will also replace these strings appearing in JavaScript strings and Vue templates. This should be a rare case, but it can be unintended. You may see errors like Missing Semicolon
or Unexpected token
in this case, for example when "p
NODE_ENV"
is transformed to ""development": "
. There are ways to work around this behavior:
For JavaScript strings, you can break the string up with a Unicode zero-width space, e.g.
'i
.mport.meta\u200b.env.MODE' For Vue templates or other HTML that gets compiled into JavaScript strings, you can use the
<wbr>
tag, e.g.i
.mport.meta.<wbr>env.MODE
.env
Files
Vite uses dotenv to load additional environment variables from the following files in your environment directory:
.env # loaded in all cases
.env.local # loaded in all cases, ignored by git
.env.[mode] # only loaded in specified mode
.env.[mode].local # only loaded in specified mode, ignored by git
Env Loading Priorities
An env file for a specific mode (e.g. .env.production
) will take higher priority than a generic one (e.g. .env
).
In addition, environment variables that already exist when Vite is executed have the highest priority and will not be overwritten by .env
files. For example, when running VITE_SOME_KEY=123 vite build
.
.env
files are loaded at the start of Vite. Restart the server after making changes.
Loaded env variables are also exposed to your client source code via i
as 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:
VITE_SOME_KEY=123
DB_PASSWORD=foobar
Only VITE_SOME_KEY
will be exposed as i
to your client source code, but DB_PASSWORD
will not.
js
console.log(import.meta.env.VITE_SOME_KEY) // 123
console.log(import.meta.env.DB_PASSWORD) // undefined
Also, Vite uses dotenv-expand to expand variables out of the box. To learn more about the syntax, check out their docs.
Note that if you want to use $
inside your environment value, you have to escape it with \
.
KEY=123
NEW_KEY1=test$foo # test
NEW_KEY2=test\$foo # test$foo
NEW_KEY3=test$KEY # test123
If you want to customize the env variables prefix, see the envPrefix option.
SECURITY NOTES
.env.*.local
files are local-only and can contain sensitive variables. You should add*.local
to your.gitignore
to avoid them being checked into git.Since any variables exposed to your Vite source code will end up in your client bundle,
VITE_*
variables should not contain any sensitive information.
IntelliSense for TypeScript
By default, Vite provides type definitions for i
in vite/client.d.ts
. While you can define more custom env variables in .env.[mode]
files, you may want to get TypeScript IntelliSense for user-defined env variables that are prefixed with VITE_
.
To achieve this, you can create an env.d.ts
in src
directory, then augment ImportMetaEnv
like this:
typescript
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_APP_TITLE: string
// more env variables...
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
If your code relies on types from browser environments such as DOM and WebWorker, you can update the lib field in tsconfig.json
.
json
{
"lib": ["WebWorker"]
}
Modes
By default, the dev server (dev
command) runs in development
mode and the build
command runs in production
mode.
This means when running vite build
, it will load the env variables from .env.production
if there is one:
# .env.production
VITE_APP_TITLE=My App
In your app, you can render the title using i
.
However, it is important to understand that mode is a wider concept than just development vs. production. A typical example is you may want to have a "staging" mode where it should have production-like behavior, but with slightly different env variables from production.
You can overwrite the default mode used for a command by passing the --mode
option flag. For example, if you want to build your app for our hypothetical staging mode:
bash
vite build --mode staging
And to get the behavior we want, we need a .env.staging
file:
# .env.staging
NODE_ENV=production
VITE_APP_TITLE=My App (staging)
Now your staging app should have production-like behavior, but display a different title from production.