Vite で環境変数(import.meta.env)が読み込めない
Vite は `VITE_` プレフィックスを付けた変数のみをクライアントへ公開する。
`.env` を置いたのに `undefined` になる典型例と、サーバー専用変数の扱いを整理する。
#env#import-meta-env#vite-prefix#dotenv#build
公開:
要約
import.meta.env.VITE_FOO が undefined になる場合、ほとんどは VITE_ プレフィックスが付いていない か dev サーバーを再起動していない ことが原因。
Vite はセキュリティ上、VITE_ プレフィックス無しの変数を一切クライアントに公開しない。
よくある原因
- プレフィックス忘れ:
.envにAPI_URL=...と書いてもクライアントからは読めない。 - 配置ミス:
viteを実行している作業ディレクトリと.envの場所が一致していない(モノレポで起こりやすい)。 - 再起動忘れ: 環境変数は起動時のスナップショットなので、
.envを編集しても HMR では反映されない。 - CI で値が無い: ローカルの
.env.localは通常.gitignoreに入っているため、CI では未定義になる。 - mode 不一致:
vite build --mode stagingなら.env.stagingが読まれる。.env.productionを置いていてもロードされない。
解決策
1. プレフィックスを付ける
# .env
VITE_API_URL=https://api.example.comconst url = import.meta.env.VITE_API_URL;ビルド時に置換されるため、シークレットを置いてはならない(公開される)。
2. サーバー側で読む場合は loadEnv
vite.config.ts から .env を読みたい時はプレフィックス無しでも loadEnv で取れる(公式ドキュメント)。
import { defineConfig, loadEnv } from "vite";
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), "");
return {
define: {
__APP_VERSION__: JSON.stringify(env.APP_VERSION),
},
};
});第 3 引数を "" にすると全変数(プレフィックス無し含む)を取得できる。
3. dev サーバーを再起動する
# Ctrl+C で停止
npm run dev4. TypeScript の型補完を追加する
// src/vite-env.d.ts
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_API_URL: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}5. mode と env ファイル名を揃える
vite build --mode staging # → .env.staging を読む