コンテンツにスキップ

環境変数を使う

Astroでは、Viteに組み込まれた環境変数のサポートを利用できます。また、いくつかのデフォルト環境変数が用意されており、現在のプロジェクトの設定値(sitebaseなど)や、プロジェクトが開発・本番のどちらで実行されているかなどにアクセスできます。

さらにAstroは、型安全に環境変数を使い、整理する方法も提供しています。これはAstroのコンテキスト内(Astroコンポーネント、ルートやエンドポイント、UIフレームワークコンポーネント、ミドルウェアなど)で利用でき、Astro設定内のスキーマ (EN)で管理します。

Astroは、Viteに組み込まれた環境変数のサポートを利用します。これらの環境変数はビルド時に静的に置き換えられ、Viteが提供する環境変数を扱うためのさまざまな機能を利用できます。

なお、すべての環境変数はサーバーサイドのコードから利用できますが、セキュリティ上の理由から、クライアントサイドのコードで利用できるのはPUBLIC_で始まる環境変数のみです。

.env
SECRET_PASSWORD=password123
PUBLIC_ANYBODY=there

この例では、PUBLIC_ANYBODYimport.meta.env.PUBLIC_ANYBODYでアクセス可能)はサーバーコードでもクライアントコードでも利用できますが、SECRET_PASSWORDimport.meta.env.SECRET_PASSWORDでアクセス可能)はサーバーサイドでのみ利用できます。

デフォルトでは、Astroはastro/client.d.ts内にimport.meta.envの型定義をあらかじめ用意しています。

.env.[mode]ファイルでその他のカスタム環境変数を定義できますが、PUBLIC_で始まるユーザー定義の環境変数についてTypeScriptのIntelliSenseを効かせたい場合があります。

そのためには、src/env.d.tsを作成してグローバルな型を拡張し、次のようにImportMetaEnvを設定します。

src/env.d.ts
interface ImportMetaEnv {
readonly DB_PASSWORD: string;
readonly PUBLIC_POKEAPI: string;
// その他の環境変数...
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}

Astroには、いくつかの環境変数が標準で組み込まれています。

  • import.meta.env.MODE: サイトが実行されているモードです。astro devの実行時はdevelopmentastro 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;

環境変数は、プロジェクトディレクトリにある.envファイルから読み込まれます。

プロジェクトディレクトリに.envファイルを作成し、変数をいくつか追加してみましょう。

.env
# これはサーバー上で実行されるときのみ利用できます!
DB_PASSWORD="foobar"
# これはどこでも利用できます!
PUBLIC_POKEAPI="https://pokeapi.co/api/v2"

ファイル名に.production.development、あるいはカスタムモード名(例: .env.testing.env.staging)を加えることもできます。これにより、状況に応じて異なる環境変数のセットを使い分けられます。

astro devastro buildコマンドは、それぞれデフォルトで"development"モードと"production"モードになります。これらのコマンドを--modeフラグ (EN)付きで実行すると、modeに別の値を渡し、対応する.envファイルを読み込めます。

これにより、APIの接続先を変えて開発サーバーを起動したり、サイトをビルドしたりできます。

Terminal window
# 「staging」APIに接続した状態で開発サーバーを起動する
npm run astro dev -- --mode staging
# 「production」APIに接続し、追加のデバッグ情報を含めてサイトをビルドする
npm run astro build -- --devOutput
# 「testing」APIに接続した状態でサイトをビルドする
npm run astro build -- --mode testing

.envファイルの詳細については、Viteのドキュメントを参照してください。

Astroは、他のファイルを読み込む前に設定ファイルを評価します。そのため、astro.config.mjs内でimport.meta.envを使って、.envファイルに設定された環境変数にアクセスすることはできません。

設定ファイル内では、CLIで設定した値など、その他の環境変数にprocess.envでアクセスできます。

また、ViteのloadEnvヘルパーを使って、.envファイルを手動で読み込むことも可能です。

astro.config.mjs
import { loadEnv } from "vite";
const { SECRET_PASSWORD } = loadEnv(process.env.NODE_ENV, process.cwd(), "");

プロジェクトの実行時に環境変数を追加することもできます。

Terminal window
PUBLIC_POKEAPI=https://pokeapi.co/api/v2 npm run dev

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ファイル内を探します。

astro:env APIを使うと、設定した環境変数に対して型安全なスキーマを定義できます。これにより、各変数をサーバーとクライアントのどちらで利用できるようにするかを指定したり、データ型や追加のプロパティを定義したりできます。

アダプターを開発していますか?アダプターをastro:envに対応させる方法 (EN)を参照してください。

スキーマを設定するには、Astroの設定にenv.schemaオプションを追加します。

astro.config.mjs
import { defineConfig } from "astro/config";
export default defineConfig({
env: {
schema: {
// ...
}
}
})

続いて、envFieldヘルパーを使って変数を文字列、数値、列挙型、真偽値として登録できます。各変数にcontext"client"または"server")とaccess"secret"または"public")を指定して環境変数の種類を定義し、optionaldefaultといった追加のプロパティをオブジェクトで渡します。

astro.config.mjs
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 devastro 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)することで、起動時にシークレットを検証するようにもできます。

現在、文字列、数値、列挙型、真偽値の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 | undefined
詳しくはAPIリファレンス (EN)を参照してください。

astro:envは仮想モジュールであり、Astroコンテキスト内でのみ使えます。たとえば、以下の場所で使えます。

  • ミドルウェア
  • Astroのルートとエンドポイント
  • Astroコンポーネント
  • フレームワークコンポーネント
  • モジュール

以下の場所では利用できないため、process.envを使う必要があります。

  • astro.config.mjs
  • スクリプト
貢献する コミュニティ スポンサー