Vite 環境で index.html から環境変数を参照する
.env
の変数(例:環境別のタグなど)を index.html
から参照したい場合、Webpack を利用した環境だと何もしなくても読み込めるのですが、Vite を利用している場合だと少し頑張る必要があります。
参考 Issue:Accessing env variables from index.html #3105
検証環境
- React v18.2.0
- Vite v3.0.7
雛形を作成
以下の内容で新規プロジェクトを作成します。
npm create vite@latest ✔ Project name: … my-vite-project ✔ Select a framework: › react ✔ Select a variant: › react-ts
.env ファイルを作成
次にルートディレクトリに.env ファイルを作成します。
VITE_MY_TITLE='環境変数だよ'
Vite のお作法に則ってVITE_
で始まる変数を定義します。
環境変数が誤ってクライアントに漏れてしまうことを防ぐために、VITE_ から始まる変数のみが Vite で処理されたコードに公開されます。
このままアプリのコンポーネント、index.html
から参照してみましょう。
App.tsx
と index.html
をそれぞれ以下のように変更します。
App.tsx
import {useState} from "react"; import "./App.css"; function App() { const [count, setCount] = useState(0); return ( <div className="App"> <h1>{import.meta.env.VITE_MY_TITLE}</h1> </div> ); } export default App;
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <script> const title = import.meta.env.VITE_MY_TITLE </script> <title>${title}</title> </head> <body> <div id="root"></div> <script type="module" src="/src/main.tsx"></script> </body> </html>
App.tsx
からは問題なく読み込めますが、index.html
からは読み込まれずに以下のエラーが起こります
Uncaught SyntaxError: Cannot use 'import.meta' outside a module
関数を定義して Vite のプラグインとして読み込ませる
Issueのコメントにあった解決方法を参考に vite.config.ts
を以下のように更新します。
import {defineConfig, loadEnv} from "vite"; import react from "@vitejs/plugin-react"; // https://vitejs.dev/config/ export default defineConfig(({mode}) => { return { plugins: [react(), htmlPlugin(loadEnv(mode, "."))], }; }); /** * Replace env variables in index.html * @see https://github.com/vitejs/vite/issues/3105#issuecomment-939703781 * @example `%VITE_MY_ENV%` * @see https://vitejs.dev/guide/api-plugin.html#transformindexhtml */ function htmlPlugin(env: ReturnType<typeof loadEnv>) { return { name: "html-transform", transformIndexHtml: { enforce: "pre" as const, transform: (html: string): string => html.replace(/%(.*?)%/g, (match, p1) => env[p1] ?? match), }, }; }
結果
index.html
から%<VITE_YOUR_VARIABLE>%
の形式で環境変数を読み込みます。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>%VITE_MY_TITLE%</title> </head> <body> <div id="root"></div> <script type="module" src="/src/main.tsx"></script> </body> </html>
コンソールのエラーが消えて index.html
から環境変数が参照できたことが確認できれば OK です。