環境変数を使う
Astroでは、Viteに組み込まれた環境変数のサポートを利用できます。また、いくつかのデフォルト環境変数が用意されており、現在のプロジェクトの設定値(siteやbaseなど)や、プロジェクトが開発・本番のどちらで実行されているかなどにアクセスできます。
さらにAstroは、型安全に環境変数を使い、整理する方法も提供しています。これはAstroのコンテキスト内(Astroコンポーネント、ルートやエンドポイント、UIフレームワークコンポーネント、ミドルウェアなど)で利用でき、Astro設定内のスキーマ (EN)で管理します。
Viteの組み込みサポート
Section titled “Viteの組み込みサポート”Astroは、Viteに組み込まれた環境変数のサポートを利用します。これらの環境変数はビルド時に静的に置き換えられ、Viteが提供する環境変数を扱うためのさまざまな機能を利用できます。
なお、すべての環境変数はサーバーサイドのコードから利用できますが、セキュリティ上の理由から、クライアントサイドのコードで利用できるのはPUBLIC_で始まる環境変数のみです。
SECRET_PASSWORD=password123PUBLIC_ANYBODY=thereこの例では、PUBLIC_ANYBODY(import.meta.env.PUBLIC_ANYBODYでアクセス可能)はサーバーコードでもクライアントコードでも利用できますが、SECRET_PASSWORD(import.meta.env.SECRET_PASSWORDでアクセス可能)はサーバーサイドでのみ利用できます。
.envファイルは設定ファイルの中では読み込まれません。
TypeScriptのIntelliSense
Section titled “TypeScriptのIntelliSense”デフォルトでは、Astroはastro/client.d.ts内にimport.meta.envの型定義をあらかじめ用意しています。
.env.[mode]ファイルでその他のカスタム環境変数を定義できますが、PUBLIC_で始まるユーザー定義の環境変数についてTypeScriptのIntelliSenseを効かせたい場合があります。
そのためには、src/にenv.d.tsを作成してグローバルな型を拡張し、次のようにImportMetaEnvを設定します。
interface ImportMetaEnv { readonly DB_PASSWORD: string; readonly PUBLIC_POKEAPI: string; // その他の環境変数...}
interface ImportMeta { readonly env: ImportMetaEnv;}デフォルト環境変数
Section titled “デフォルト環境変数”Astroには、いくつかの環境変数が標準で組み込まれています。
import.meta.env.MODE: サイトが実行されているモードです。astro devの実行時はdevelopment、astro buildの実行時はproductionになります。import.meta.env.PROD: サイトが本番環境で実行されている場合はtrue、それ以外はfalseになります。import.meta.env.DEV: サイトが開発環境で実行されている場合はtrue、それ以外はfalseになります。常にimport.meta.env.PRODの逆の値です。import.meta.env.BASE_URL: サイトが配信されるベースURLです。base設定オプション (EN)によって決まります。import.meta.env.SITE: プロジェクトのastro.configで指定されたsiteオプション (EN)が設定されます。
これらは、他の環境変数と同じように使えます。
const isProd = import.meta.env.PROD;const isDev = import.meta.env.DEV;環境変数を設定する
Section titled “環境変数を設定する”.envファイル
Section titled “.envファイル”環境変数は、プロジェクトディレクトリにある.envファイルから読み込まれます。
プロジェクトディレクトリに.envファイルを作成し、変数をいくつか追加してみましょう。
# これはサーバー上で実行されるときのみ利用できます!DB_PASSWORD="foobar"
# これはどこでも利用できます!PUBLIC_POKEAPI="https://pokeapi.co/api/v2"ファイル名に.productionや.development、あるいはカスタムモード名(例: .env.testing、.env.staging)を加えることもできます。これにより、状況に応じて異なる環境変数のセットを使い分けられます。
astro devとastro buildコマンドは、それぞれデフォルトで"development"モードと"production"モードになります。これらのコマンドを--modeフラグ (EN)付きで実行すると、modeに別の値を渡し、対応する.envファイルを読み込めます。
これにより、APIの接続先を変えて開発サーバーを起動したり、サイトをビルドしたりできます。
# 「staging」APIに接続した状態で開発サーバーを起動するnpm run astro dev -- --mode staging
# 「production」APIに接続し、追加のデバッグ情報を含めてサイトをビルドするnpm run astro build -- --devOutput
# 「testing」APIに接続した状態でサイトをビルドするnpm run astro build -- --mode testing# 「staging」APIに接続した状態で開発サーバーを起動するpnpm astro dev --mode staging
# 「production」APIに接続し、追加のデバッグ情報を含めてサイトをビルドするpnpm astro build --devOutput
# 「testing」APIに接続した状態でサイトをビルドするpnpm astro build --mode testing# 「staging」APIに接続した状態で開発サーバーを起動するyarn astro dev --mode staging
# 「production」APIに接続し、追加のデバッグ情報を含めてサイトをビルドするyarn astro build --devOutput
# 「testing」APIに接続した状態でサイトをビルドするyarn astro build --mode testing.envファイルの詳細については、Viteのドキュメントを参照してください。
Astro設定ファイル内
Section titled “Astro設定ファイル内”Astroは、他のファイルを読み込む前に設定ファイルを評価します。そのため、astro.config.mjs内でimport.meta.envを使って、.envファイルに設定された環境変数にアクセスすることはできません。
設定ファイル内では、CLIで設定した値など、その他の環境変数にprocess.envでアクセスできます。
また、ViteのloadEnvヘルパーを使って、.envファイルを手動で読み込むことも可能です。
import { loadEnv } from "vite";
const { SECRET_PASSWORD } = loadEnv(process.env.NODE_ENV, process.cwd(), "");pnpmでは、プロジェクトに直接インストールされていないモジュールをインポートできません。pnpmを使っている場合は、loadEnvヘルパーを使うためにviteをインストールする必要があります。
pnpm add -D viteCLIを使う
Section titled “CLIを使う”プロジェクトの実行時に環境変数を追加することもできます。
PUBLIC_POKEAPI=https://pokeapi.co/api/v2 npm run devPUBLIC_POKEAPI=https://pokeapi.co/api/v2 pnpm run devPUBLIC_POKEAPI=https://pokeapi.co/api/v2 yarn run dev環境変数を取得する
Section titled “環境変数を取得する”Astroでは、環境変数へのアクセスにprocess.envではなく、ES2020で追加されたimport.meta機能を利用したimport.meta.envを使います。
たとえば、PUBLIC_POKEAPI環境変数を取得するにはimport.meta.env.PUBLIC_POKEAPIを使います。
// import.meta.env.SSR === true のときconst data = await db(import.meta.env.DB_PASSWORD);
// import.meta.env.SSR === false のときconst data = fetch(`${import.meta.env.PUBLIC_POKEAPI}/pokemon/squirtle`);SSRを使う場合、環境変数は使用しているSSRアダプターに応じて実行時にアクセスできます。ほとんどのアダプターではprocess.envで環境変数にアクセスできますが、一部のアダプターは動作が異なります。たとえばDenoアダプターではDeno.env.get()を使います。Cloudflareアダプターを使う場合に環境変数を扱う方法については、Cloudflareランタイムへのアクセス方法 (EN)を参照してください。Astroはまずサーバー環境に変数があるか確認し、存在しない場合は.envファイル内を探します。
型安全な環境変数
Section titled “型安全な環境変数”astro:env APIを使うと、設定した環境変数に対して型安全なスキーマを定義できます。これにより、各変数をサーバーとクライアントのどちらで利用できるようにするかを指定したり、データ型や追加のプロパティを定義したりできます。
astro:envに対応させる方法 (EN)を参照してください。
基本的な使い方
Section titled “基本的な使い方”スキーマを定義する
Section titled “スキーマを定義する”スキーマを設定するには、Astroの設定にenv.schemaオプションを追加します。
import { defineConfig } from "astro/config";
export default defineConfig({ env: { schema: { // ... } }})続いて、envFieldヘルパーを使って変数を文字列、数値、列挙型、真偽値として登録できます。各変数にcontext("client"または"server")とaccess("secret"または"public")を指定して環境変数の種類を定義し、optionalやdefaultといった追加のプロパティをオブジェクトで渡します。
import { defineConfig, envField } from "astro/config";
export default defineConfig({ env: { schema: { API_URL: envField.string({ context: "client", access: "public", optional: true }), PORT: envField.number({ context: "server", access: "public", default: 4321 }), API_SECRET: envField.string({ context: "server", access: "secret" }), } }})型はastro devやastro buildの実行時に自動生成されますが、astro syncを実行して型のみを生成することもできます。
スキーマで定義した変数を使う
Section titled “スキーマで定義した変数を使う”定義した変数を、/clientまたは/serverモジュールからインポートして使います。
---import { API_URL } from "astro:env/client";import { API_SECRET_TOKEN } from "astro:env/server";
const data = await fetch(`${API_URL}/users`, { method: "GET", headers: { "Content-Type": "application/json", "Authorization": `Bearer ${API_SECRET_TOKEN}` },})---
<script> import { API_URL } from "astro:env/client";
fetch(`${API_URL}/ping`)</script>環境変数には、スキーマで定義するcontext("client"または"server")とaccess("secret"または"public")の設定の組み合わせによって決まる、3つの種類があります:
-
パブリックなクライアント変数: この変数は最終的なクライアントバンドルとサーバーバンドルの両方に含まれ、
astro:env/clientモジュールを通じてクライアントとサーバーの両方からアクセスできます。import { API_URL } from "astro:env/client"; -
パブリックなサーバー変数: この変数は最終的なサーバーバンドルに含まれ、
astro:env/serverモジュールを通じてサーバー上でアクセスできます。import { PORT } from "astro:env/server"; -
シークレットサーバー変数: この変数は最終的なバンドルには含まれず、
astro:env/serverモジュールを通じてサーバー上でアクセスできます。import { API_SECRET } from "astro:env/server";デフォルトでは、
astro:env/serverモジュールから何かがインポートされるたびに、すべてのシークレットが検証されます。つまり、インポートされていないシークレットも検証される場合があります。ビルド時にこの検証を満たすために、ダミーの環境変数を渡す必要があるかもしれません。また、
validateSecrets: trueを設定 (EN)することで、起動時にシークレットを検証するようにもできます。
シークレットクライアント変数は、データを安全にクライアントへ送信する方法がないためサポートされていません。したがって、スキーマでcontext: "client"とaccess: "secret"の両方を設定することはできません。
現在、文字列、数値、列挙型、真偽値の4つのデータ型がサポートされています。
import { envField } from "astro/config";
envField.string({ // context と access optional: true, default: "foo",})
envField.number({ // context と access optional: true, default: 15,})
envField.boolean({ // context と access optional: true, default: true,})
envField.enum({ // context と access values: ["foo", "bar", "baz"], optional: true, default: "baz",})envFieldで指定できる検証用フィールドの完全な一覧については、envField APIリファレンス (EN)を参照してください。
シークレットを動的に取得する
Section titled “シークレットを動的に取得する”スキーマを定義していても、特定のシークレットの生の値を取得したい場合や、スキーマで定義されていないシークレットを取得したい場合があります。そのような場合は、astro:env/serverからエクスポートされているgetSecret()を使えます。
import { FOO, // boolean getSecret} from "astro:env/server";
getSecret("FOO"); // string | undefinedastro:envは仮想モジュールであり、Astroコンテキスト内でのみ使えます。たとえば、以下の場所で使えます。
- ミドルウェア
- Astroのルートとエンドポイント
- Astroコンポーネント
- フレームワークコンポーネント
- モジュール
以下の場所では利用できないため、process.envを使う必要があります。
astro.config.mjs- スクリプト