安全に環境変数を扱うならこれ!@t3-oss/env-nextjs の使い方と導入メリット
あなたは今までに環境変数をタイポした回数を覚えていますか?
Next.js で環境変数を使うとき、こんな経験はありませんか?
-
.env.localにミスがあっても気づかず、デプロイ後にエラー - クライアントとサーバーのスコープが曖昧で混乱
- 「あれ、この変数って
NEXT_PUBLIC_つけるんだっけ?」
そんな悩みを一気に解決してくれるのが、T3 Stack で使われている @t3-oss/env-nextjs です。
このライブラリを使えば、環境変数を型安全に、かつ安心して管理することができます。
本記事では、@t3-oss/env-nextjs の導入手順から実践的な使い方、よくある落とし穴とその対処法までを丁寧に解説します。
なぜ @t3-oss/env-nextjs が必要か?
Next.js では process.env を直接使って環境変数にアクセスできます。しかし、以下のような課題があります。
| 課題 | 問題点 |
|---|---|
| 型がない | 変数名の typo や型ミスに気づけない |
| バリデーションできない | 値が空でも気づかない |
| クライアント/サーバーの混在 | セキュリティリスクや混乱の元 |
| 環境ごとの管理が難しい |
.env が肥大化しがち |
これらを解決するために、T3 Stack の開発者たちが設計したのが @t3-oss/env-nextjs です。
特徴とメリット
- ✅ Zod によるバリデーション
- ✅ サーバー用 / クライアント用 に明確に分離
- ✅ 型補完が効くので開発効率もアップ
- ✅
NEXT_PUBLIC_の強制でセキュリティ担保 - ✅ App Router / TypeScript 環境でも安心して使える
インストール
npm install @t3-oss/env-nextjs zod
基本の使い方
まずは env.mjs(または env.ts)ファイルをプロジェクトのルートに作成します。
env.mjs
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";
export const env = createEnv({
server: {
DATABASE_URL: z.string().url(),
},
client: {
NEXT_PUBLIC_API_URL: z.string().url(),
},
runtimeEnv: {
DATABASE_URL: process.env.DATABASE_URL,
NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,
},
});
🔒 クライアントで使う変数は必ず
NEXT_PUBLIC_で始める必要があります。これがセキュリティの第一歩!
.env.local に定義
DATABASE_URL=https://db.example.com
NEXT_PUBLIC_API_URL=https://api.example.com
.env.local は .gitignore に含めておきましょう。共有には .env.example を用意するのがベストプラクティスです。
使用例
✅ サーバーサイド
import { env } from "@/env";
export async function fetchData() {
const res = await fetch(`${env.DATABASE_URL}/data`);
return res.json();
}
✅ クライアントサイド
"use client";
import { env } from "@/env";
export default function Page() {
return <div>API: {env.NEXT_PUBLIC_API_URL}</div>;
}
よくあるエラーと対処法
❌ runtimeEnv is missing
→ createEnv の runtimeEnv に process.env.XYZ を忘れていませんか?
❌ ZodError: Invalid URL
→ .env.local の値が z.string().url() に合っていない可能性があります。
❌ クライアントから DATABASE_URL を参照している
→ サーバー専用変数をクライアントで使うとビルドエラーになります(これは 意図的なガード です)
ベストプラクティスまとめ
| 項目 | 内容 |
|---|---|
| 変数の命名 | クライアントで使うものは NEXT_PUBLIC_
|
| 型の定義 |
z.string(), z.number(), z.enum([...]) など |
| ファイル配置 |
env.ts or env.mjs を /src に置くのが一般的 |
| テスト環境 |
.env.test を活用し、テスト用に別定義するのも有効 |
おわりに
@t3-oss/env-nextjs は一見地味ですが、堅牢でセキュアな開発を支える最重要ライブラリのひとつです。
とくに App Router + TypeScript 環境において、「何がクライアントに漏れてよくて、何がダメなのか」を明確にしてくれる点はとても大きな価値があります。
ぜひあなたの Next.js プロジェクトにも導入して、環境変数の管理を「型安全・セキュア・安心」なものにしていきましょう!
参考リンク
- GitHub: @t3-oss/env-nextjs
- T3 Stack 公式: https://create.t3.gg/
- Zod: https://zod.dev
✍️ 使用した感想
T3 Stack の思想はかなりとんがっていますが @t3-oss/env-nextjs は部分的に「型安全さ」を取り入れる事ができてなかなか良いなあ、と思いました。おしまい。
Discussion
なお、この記事の99%はAIが書いています。もし、間違いがあったらごめんなさい。