できない.dev

Vite で環境変数(import.meta.env)が読み込めない

Vite は `VITE_` プレフィックスを付けた変数のみをクライアントへ公開する。
`.env` を置いたのに `undefined` になる典型例と、サーバー専用変数の扱いを整理する。

#env#import-meta-env#vite-prefix#dotenv#build

公開:

要約

import.meta.env.VITE_FOOundefined になる場合、ほとんどは VITE_ プレフィックスが付いていないdev サーバーを再起動していない ことが原因。
Vite はセキュリティ上、VITE_ プレフィックス無しの変数を一切クライアントに公開しない。

よくある原因

  1. プレフィックス忘れ: .envAPI_URL=... と書いてもクライアントからは読めない。
  2. 配置ミス: vite を実行している作業ディレクトリと .env の場所が一致していない(モノレポで起こりやすい)。
  3. 再起動忘れ: 環境変数は起動時のスナップショットなので、.env を編集しても HMR では反映されない。
  4. CI で値が無い: ローカルの .env.local は通常 .gitignore に入っているため、CI では未定義になる。
  5. mode 不一致: vite build --mode staging なら .env.staging が読まれる。.env.production を置いていてもロードされない。

解決策

1. プレフィックスを付ける

# .env
VITE_API_URL=https://api.example.com
const 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 dev

4. 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 を読む

この記事は役立ちましたか?