はじめに
Cloudflare workers上でNext.jsを動かしている場合, process.env. で環境変数が取得できません.
上のように, 環境変数やシークレットなどを登録している状態で,
const resend = new Resend(process.env.RESEND_API_KEY)
のように使用すると, ビルドプロセスで以下のエラーが出ました.
Error: Missing API key. Pass it to the constructor new Resend("re_123")
このように表示され, 環境変数が登録されていないよ! と怒られてしまいました.
解決方法
getCloudflareContext()を使います.
//utils/env.ts
import { getCloudflareContext } from '@opennextjs/cloudflare';
export const getEnv = (key: string): string | undefined => {
// 1. Cloudflare Workers環境での取得を試みる
try {
const cfContext = getCloudflareContext()
if (cfContext && cfContext.env && (cfContext.env as any)[key]) {
return (cfContext.env as any)[key]
}
} catch (e) {
// ローカルの npm run dev など、Cloudflareコンテキストがない場合はこちら
}
// 2. フォールバックとして標準の process.env を見る
// (ローカル開発時や、ビルド時に埋め込まれた変数はここにある)
return process.env[key]
}
//利用する側はこちら
import { getEnv } from '@/utils/env';
const apiKey = getEnv('RESEND_API_KEY');
const resend = new Resend(apiKey);
上記のようにすることで, ローカルでもcloudflare workers上でも, 同じコードで環境変数を取得することができます.
その他の注意事項
cloudflare workersの場合、シークレットとして保存すると新しいビルドでも引き継がれますが、環境変数として保存すると、ビルドのたびに消えました.
自分は環境変数として登録しなくてもいい情報でもシークレットとして登録してしまっていますが(GA4のtag IDなど), もっといい方法があればぜひコメントで教えてください(公式はwrangler.tomlで管理することを想定しているようですが, .gitignoreにwrangler.tomlは含められず, のちのち公開する可能性があることを考えると, この管理方法は使いたくない気がします).
