お問い合わせフォームを作って本番環境にデプロイしたが、送信しても何も届かない。フォームのURLが空文字になっていた。
原因はAstroとNetlifyの組み合わせによる、よくある落とし穴だった。
何が起きていたか
Astroで import.meta.env.PUBLIC_MAILFORM_URL を使ってフォームの送信先URLを取得していた。
---
const mailformUrl = import.meta.env.PUBLIC_MAILFORM_URL;
---
<input type="hidden" id="mailform-url" value={mailformUrl || ''} />
Netlifyのダッシュボードで環境変数を設定したにもかかわらず、HTMLを確認すると value が空だった。
<!-- 空になっている -->
<input type="hidden" id="mailform-url" value>
原因
AstroはSSG(静的サイト生成)なので、環境変数はビルド実行時にHTMLへ焼き込まれる。
これはNextやNuxtのSSRとは根本的に異なる。実行時に環境変数を読むのではなく、ビルド時に確定した値が静的ファイルに埋め込まれる。
Netlifyで環境変数を設定した後に再ビルドしなければ、変数が存在しなかった状態でビルドされたファイルが使われ続ける。
もう一つの落とし穴:スコープ設定
NetlifyはEnvironment Variablesにスコープ設定がある。
| スコープ | 用途 |
|---|---|
| Builds | ビルド実行時に使用 ← Astroはこれが必要 |
| Runtime | サーバー関数の実行時のみ |
| All scopes | 両方 |
「Builds」か「All scopes」になっていないと、Astroのビルド中に変数が見えず空文字で焼き込まれる。
解決手順
- Netlifyの Site configuration → Environment variables を開く
- 対象の変数の Scopes が Builds または All scopes になっているか確認
- なっていなければ変更して保存
- Deploys → Trigger deploy → Deploy site で再ビルドする
再ビルドすれば環境変数が正しく埋め込まれたHTMLが生成される。
確認方法
デプロイ後にブラウザの開発者ツールでHTMLを確認する。
<!-- 正常 -->
<input type="hidden" id="mailform-url" value="https://script.google.com/macros/s/...">
<!-- 異常(空) -->
<input type="hidden" id="mailform-url" value>
SSGの場合、実行時に値を注入する手段がないため、空のまま動くことはない。ビルドログを見て環境変数が認識されているかも確認できる。
デプロイ後に環境変数を追加・変更したら必ず再ビルドする、というのがAstro + Netlifyの鉄則だ。