🎉

T3 Envで環境変数をタイプセーフに扱う

2023/07/08に公開

はじめに

  • 環境変数を扱うときに、型が string | undefined になり困ったり、環境変数名を打ち間違えたり、型が異なっていたりすることがあります。
  • T3 Env[1] を利用し、Next.js で環境変数のタイプセーフに扱う方法を紹介します。

https://env.t3.gg/

作業コードはこちらにあります。

https://github.com/hayato94087/next-t3env-sample

T3 Env

Next.js の App Router でタイプセーフに環境変数を扱う場合は、T3-env がおすすめです。

T3 Env は以下の特徴があります。

サジェスト

サジェストで環境変数を表示してくれます。

タイプセーフ

環境変数に型付けし、TypeScript でタイプセーフに環境変数を扱えます。

process.env を使う場合、型が string | undefined になるため、環境変数の値を利用する際に、undefined のチェックを行う必要があります。これを回避できます。

環境変数の説明

環境変数の説明を追加できます。

ビルド時の型検証

T3-env はビルド時に型の検証し、エラーを出力します。型の検証は Zod[2]を利用しており、Zod の範囲であれば型の検証が可能です。

  • 環境変数が定義されていない(例:DEBUG_MESSAGE
  • 環境変数の型・制約が異なる(例:DATABASE_URLDEBUG_EMAILDEBUG_EMOJI

以下がビルドエラーの例です。

$ pnpm build

- info Loaded env from /Users/hayato94087/Private/next-t3env-sample/.env
❌ Invalid environment variables: {
  DATABASE_URL: [ 'Invalid url' ],
  DEBUG_EMAIL: [ 'Invalid email' ],
  DEBUG_EMOJI: [ 'Invalid emoji' ],
  DEBUG_MESSAGE: [ 'Required' ]

https://zod.dev/

型の検証はもちろんですが、タイポなどもこれで回避できます。

サイト

以下がライブラリーサイトです。

https://env.t3.gg/

紹介されている動画

https://www.youtube.com/watch?v=UnDw3_7_9gc

新規にプロジェクトを作成

作業するプロジェクトを新規に作成していきます。

長いので、折りたたんでおきます。

新規プロジェクト作成と初期環境構築の手順詳細
$ pnpm create next-app@latest next-t3env-sample --typescript --eslint --import-alias "@/*" --src-dir --use-pnpm --tailwind --app
$ cd next-t3env-sample

以下の通り不要な設定を削除し、プロジェクトの初期環境を構築します。

src/app/globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;
src/app/page.tsx
export default function Home() {
  return (
    <main className="text-lg">
      テストページ
    </main>
  )
}
src/app/layout.tsx
import "./globals.css";

export const metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="ja">
      <body className="">{children}</body>
    </html>
  );
}
tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
    "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  plugins: [],
};
tailwind.config.js
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "plugins": [
      {
        "name": "next"
      }
    ],
+    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"],
+      "@app/*": ["./src/app/*"],
+      "@components/*": ["./src/components/*"]
    }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
  "exclude": ["node_modules"]
}

コミットします。

$ pnpm build
$ git add .
$ git commit -m "新規にプロジェクトを作成し, 作業環境を構築"

T3-envのパッケージをインストール

$ pnpm add @t3-oss/env-nextjs zod

スキーマを作成

スキーマの作成方法は 2 種類あります。ここでは、サーバサイドとクライアントの環境変数を同一ファイルに記述する方法を紹介します。

$ touch src/env.mjs
src/env.mjs
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";

export const env = createEnv({
  // サーバサイドの環境変数
  server: {
    /** データベースの接続先のURL */
    DATABASE_URL: z.string().url(),
    /** OPEN AI の API KEY */
    API_KEY: z.string().min(1),
    /** メールアドレス */
    DEBUG_EMAIL: z.string().email(),
    /** デバッグ用の絵文字 */
    DEBUG_EMOJI: z.string().emoji(),
    /** デバッグ用のメッセージ */
    DEBUG_MESSAGE: z.string().min(5),
  },
  // クライアントサイドの環境変数
  client: {
    // クライアントサイドで利用するキー
    NEXT_PUBLIC_PUBLISHABLE_KEY: z.string().min(1),
    /** デバッグ用のメッセージ */
    NEXT_PUBLIC_DEBUG_MESSAGE: z.string().min(5),
  },
  // If you're using Next.js < 13.4.4, you'll need to specify the runtimeEnv manually
  // runtimeEnv: {
  //   DATABASE_URL: process.env.DATABASE_URL,
  //   API_KEY: process.env.API_KEY,
  //   NEXT_PUBLIC_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_PUBLISHABLE_KEY,
  // },
  // For Next.js >= 13.4.4, you only need to destructure client variables:
  experimental__runtimeEnv: {
    NEXT_PUBLIC_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_PUBLISHABLE_KEY,
    NEXT_PUBLIC_DEBUG_MESSAGE: process.env.NEXT_PUBLIC_DEBUG_MESSAGE,
  },
});

スキーマのポイントを説明します。

ポイント1:サーバーサイドで利用する環境変数

server はサーバーサイドで利用する環境変数を定義します。

src/env.mjs(省略版)
...
export const env = createEnv({
  // サーバサイドの環境変数
  server: {
    /** データベースの接続先のURL */
    DATABASE_URL: z.string().url(),
    /** OPEN AI の API KEY */
    API_KEY: z.string().min(1),
    /** メールアドレス */
    DEBUG_EMAIL: z.string().email(),
    /** デバッグ用の絵文字 */
    DEBUG_EMOJI: z.string().emoji(),
    /** デバッグ用のメッセージ */
    DEBUG_MESSAGE: z.string().min(5),
  },
  ...
});

ポイント2:クライアントで利用する環境変数

client はクライアントで利用する環境変数を定義します。NEXT_PUBLIC_PUBLISHABLE_KEYNEXT_PUBLIC_DEBUG_MESSAGE はクライアントで利用を想定した環境変数です。

src/env.mjs(省略版)
...
export const env = createEnv({
  ...
  // クライアントサイドの環境変数
  client: {
    // クライアントサイドで利用するキー
    NEXT_PUBLIC_PUBLISHABLE_KEY: z.string().min(1),
    /** デバッグ用のメッセージ */
    NEXT_PUBLIC_DEBUG_MESSAGE: z.string().min(5),
  },
  ...
  // For Next.js >= 13.4.4, you only need to destructure client variables:
  experimental__runtimeEnv: {
    NEXT_PUBLIC_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_PUBLISHABLE_KEY,
    NEXT_PUBLIC_DEBUG_MESSAGE: process.env.NEXT_PUBLIC_DEBUG_MESSAGE,
  },
});

ポイント3:zodを利用した型定義

zod を利用し環境変数の型を定義します。

  • DATABASE_URL は URL 形式
  • API_KEY は 1 文字以上の文字列
  • DEBUG_EMAIL はメールアドレス形式
  • DEBUG_EMOJI は絵文字を含む文字列
  • DEBUG_MESSAGE は 5 文字以上の文字列
  • NEXT_PUBLIC_PUBLISHABLE_KEY は 1 文字以上の文字列
  • NEXT_PUBLIC_DEBUG_MESSAGE は 5 文字以上の文字列

https://zod.dev/

src/env.mjs(省略版)
...
export const env = createEnv({
  // サーバサイドの環境変数
  server: {
    /** データベースの接続先のURL */
    DATABASE_URL: z.string().url(),
    /** OPEN AI の API KEY */
    API_KEY: z.string().min(1),
    /** メールアドレス */
    DEBUG_EMAIL: z.string().email(),
    /** デバッグ用の絵文字 */
    DEBUG_EMOJI: z.string().emoji(),
    /** デバッグ用のメッセージ */
    DEBUG_MESSAGE: z.string().min(5),
  },
  // クライアントサイドの環境変数
  client: {
    // クライアントサイドで利用するキー
    NEXT_PUBLIC_PUBLISHABLE_KEY: z.string().min(1),
    /** デバッグ用のメッセージ */
    NEXT_PUBLIC_DEBUG_MESSAGE: z.string().min(5),
  },
  ...
});

ポイント4:環境変数の説明を追加

環境変数の説明をコメントを追記できます。実際のエディターでの資料例は以下の画像です。

設定は以下のようになります。

src/env.mjs(省略版)
...
export const env = createEnv({
  // サーバサイドの環境変数
  server: {
    /** データベースの接続先のURL */
    DATABASE_URL: z.string().url(),
    /** OPEN AI の API KEY */
    API_KEY: z.string().min(1),
    /** メールアドレス */
    DEBUG_EMAIL: z.string().email(),
    /** デバッグ用の絵文字 */
    DEBUG_EMOJI: z.string().emoji(),
    /** デバッグ用のメッセージ */
    DEBUG_MESSAGE: z.string().min(5),
  },
  // クライアントサイドの環境変数
  client: {
    // クライアントサイドで利用するキー
    NEXT_PUBLIC_PUBLISHABLE_KEY: z.string().min(1),
    /** デバッグ用のメッセージ */
    NEXT_PUBLIC_DEBUG_MESSAGE: z.string().min(5),
  },
  ...
});

以下が実際の環境変数の説明一覧です。

環境変数 説明
DATABASE_URL データベースの接続先のURL
API_KEY OPEN AI の API KEY
DEBUG_EMAIL メールアドレス
DEBUG_EMOJI デバッグ用の絵文字
DEBUG_MESSAGE デバッグ用のメッセージ
NEXT_PUBLIC_PUBLISHABLE_KEY クライアントサイドで利用するキー
NEXT_PUBLIC_DEBUG_MESSAGE デバッグ用のメッセージ

ポイント5:環境変数の設定ファイルの読み込み

詳細は後ほど説明しますが、コード上で環境変数を取り扱う場合は、env.mjsimport し、env からアクセスします。

import { env } from "@/env.mjs";

export default function Home() {
  const debugMessage = env.DEBUG_MESSAGE;
  return (
    <main className="text-lg">
      <div>{debugMessage}</div>
    </main>
  );
}

これにより、サジェストで環境変数を表示してくれます。

また、環境変数に型付けし、TypeScript でタイプセーフに環境変数を扱えます。as string とかしなくてすみます。

ポインㇳ6:サーバサイドとクライアントの環境変数を同時に記述

クライアントとサーバサイドで利用する環境変数の設定を 1 つのファイルで対応できます。良い点としてサーバサイドとクライアントを意識して環境変数の設定ファイル(env.mjs)の読み込み先を変更する必要がありません。

一方で、同一ファイルに記述するデメリットがあります。クライアントにサーバサイドで利用している環境変数の名前が漏れてしまうことです。サーバサイドの環境が可視化されるのはセキュリティ的には望ましくないので、次に紹介するスキーマを分割して記述することをおすすめします。

https://env.t3.gg/docs/nextjs

スキーマを分割

サーバーサイドとクライアントの環境変数ファイルを分割します。

$ mkdir -p src/env/
$ touch src/env/client.mjs
$ touch src/env/server.mjs
src/env/server.mjs
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";

export const env = createEnv({
  // サーバサイドの環境変数
  server: {
    /** データベースの接続先のURL */
    DATABASE_URL: z.string().url(),
    /** OPEN AI の API KEY */
    API_KEY: z.string().min(1),
    /** メールアドレス */
    DEBUG_EMAIL: z.string().email(),
    /** デバッグ用の絵文字 */
    DEBUG_EMOJI: z.string().emoji(),
    /** デバッグ用のメッセージ */
    DEBUG_MESSAGE: z.string().min(5),
  },
  experimental__runtimeEnv: {},
});
src/env/client.mjs
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";

export const env = createEnv({
  // クライアントサイドの環境変数
  client: {
    // クライアントサイドで利用するキー
    NEXT_PUBLIC_PUBLISHABLE_KEY: z.string().min(1),
    /** デバッグ用のメッセージ */
    NEXT_PUBLIC_DEBUG_MESSAGE: z.string().min(5),
  },
  experimental__runtimeEnv: {
    NEXT_PUBLIC_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_PUBLISHABLE_KEY,
    NEXT_PUBLIC_DEBUG_MESSAGE: process.env.NEXT_PUBLIC_DEBUG_MESSAGE,
  },
});

コミットします。

コミット処理
$ pnpm build
$ git add .
$ git commit -m "T3-env のパッケージを追加しスキーマを作成"

スキーマは作成しました。が、この時点では、next.config.js にて作成したスキーマを利用する設定をしていないため、ビルド時にスキーマ検証は行われません。よって、環境変数のファイル(env.local)がなくても、エラーになりません。

ビルド時にスキーマ検証できるよう設定

ビルド時に T3-env でスキーマをベースに環境変数を検証できるようにします。next.config.jsimport に対応していないため、next.config.mjs に変更します。

$ mv next.config.js next.config.mjs

先程のスキーマを import します。

next.config.mjs
// 同一ファイルを利用する場合
// import "./src/env.mjs";

// ファイルを分割する場合
import "./src/env/client.mjs";
import "./src/env/server.mjs";

/** @type {import('next').NextConfig} */
const nextConfig = {};

export default nextConfig;

ビルドしてみる

では、実際にビルドして、環境変数の型検証ができるか確認してみます。なお、現在は、.env.local が存在しない状態です。

$ ls .env*

zsh: no matches found: .env*

ビルドすると、NEXT_PUBLIC_PUBLISHABLE_KEYDEBUG_CLIENT_MESSAGE が定義されていないとエラーが出ます。

$ pnpm build

❌ Invalid environment variables: {
  NEXT_PUBLIC_PUBLISHABLE_KEY: [ 'Required' ],
  NEXT_PUBLIC_DEBUG_MESSAGE: [ 'Required' ]
}

エラーが出た環境変数を定義します。

$ touch .env.local
.env.local
NEXT_PUBLIC_PUBLISHABLE_KEY=oNSApA4gVsqVD05EHSYP
NEXT_PUBLIC_DEBUG_MESSAGE="HELLO CLIENT"

再度、ビルドすると、今度はサーバサイドの環境変数が定義されていないというエラーが返ります。

$ pnpm build

❌ Invalid environment variables: {
  DATABASE_URL: [ 'Required' ],
  API_KEY: [ 'Required' ],
  DEBUG_EMAIL: [ 'Required' ],
  DEBUG_EMOJI: [ 'Required' ],
  DEBUG_MESSAGE: [ 'Required' ]
}

zod を利用し環境変数の型を定義されています。

  • DATABASE_URL は URL 形式
  • API_KEY は 1 文字以上の文字列
  • DEBUG_EMAIL はメールアドレス形式
  • DEBUG_EMOJI は絵文字を含む文字列
  • DEBUG_MESSAGE は 5 文字以上の文字列
  • NEXT_PUBLIC_PUBLISHABLE_KEY は 1 文字以上の文字列
  • NEXT_PUBLIC_DEBUG_MESSAGE は 5 文字以上の文字列

わざと、誤った値を入れていきます。

.env.local
NEXT_PUBLIC_PUBLISHABLE_KEY=oNSApA4gVsqVD05EHSYP
DEBUG_CLIENT_MESSAGE="HELLO CLIENT"
+DATABASE_URL=OYrQqOcndG36oKll3xrb
+API_KEY=""
+DEBUG_EMAIL="aa"
+DEBUG_EMOJI="hogehoge"
+DEBUG_MESSAGE="a"

ビルドします。以下の通りエラーが出ます。

  • DATABASE_URL は URL 形式ではない
  • API_KEY は 1 文字以上の文字列ではない
  • DEBUG_EMAIL はメールアドレス形式ではない
  • DEBUG_EMOJI は絵文字を含む文字列ではない
  • DEBUG_MESSAGE は 5 文字以上の文字列ではない
$ pnpm build

❌ Invalid environment variables: {
  DATABASE_URL: [ 'Invalid url' ],
  API_KEY: [ 'String must contain at least 1 character(s)' ],
  DEBUG_EMAIL: [ 'Invalid email' ],
  DEBUG_EMOJI: [ 'Invalid emoji' ],
  DEBUG_MESSAGE: [ 'String must contain at least 5 character(s)' ]

では、正しい情報を入力します。

.env.local
NEXT_PUBLIC_PUBLISHABLE_KEY=oNSApA4gVsqVD05EHSYP
NEXT_PUBLIC_DEBUG_MESSAGE="HELLO CLIENT"
-DATABASE_URL=OYrQqOcndG36oKll3xrb
-API_KEY=""
-DEBUG_EMAIL="aa"
-DEBUG_EMOJI="hogehoge"
-DEBUG_MESSAGE="a"
+DATABASE_URL=https://hogehoge.com/database
+API_KEY="3KflaKDOQ0F"
+DEBUG_EMAIL="hogehoge@gmail.com"
+DEBUG_EMOJI="👍"
+DEBUG_MESSAGE="HELLO SERVER"

ビルドします。形式は正しいので、エラーは出ません。

$ pnpm build

コミットします。

コミット処理
$ pnpm build
$ git add .
$ git commit -m "next.config.mjs と T3 envを連携"

動作確認

それではそれぞれのユースケースで動作確認していきましょう。

ケース1:サーバサイドで環境変数を利用

クライアントとサーバサイドのスキーマを同一ファイルで定義しているスキーマファイル(env.mjs)を読み込み、環境変数を env からアクセスします。

$ mkdir -p src/app/case-1
$ touch src/app/case-1/page.tsx
src/app/case-1/page.tsx
// スキーマを読み込む方法は二種類
// クライアントとサーバサイドのスキーマを同一ファイルで定義しているファイルを読み込む
import { env } from "@/env.mjs";

export default function Home() {
  // スキーマをを読み込むことでタイプセーフに環境変数を扱える
  const databaseUrl = env.DATABASE_URL;
  const apiKey = env.API_KEY;
  const debugEmail = env.DEBUG_EMAIL;
  const debugEmoji = env.DEBUG_EMOJI;
  const debugMessage = env.DEBUG_MESSAGE;

  // サーバサイドのログに出力される 
  // 今回はビルド時に吐き出される
  console.log("\n")
  console.log(`Server Log`)
  console.log(`DATABASE_URL : ${databaseUrl}`);
  console.log(`API_KEY : ${apiKey}`);
  console.log(`DEBUG_EMAIL : ${debugEmail}`);
  console.log(`DEBUG_EMOJI : ${debugEmoji}`);
  console.log(`DEBUG_MESSAGE : ${debugMessage}`);

  return (
    <main className="text-lg">
      サーバサイド処理
    </main>
  );
}

ビルドします。ビルドすると console.log で出力したログが吐き出されます。

$ pnpm build

- info Loaded env from /Users/hayato94087/Private/next-t3env-sample/.env.local
- info Creating an optimized production build  
- info Compiled successfully
- info Linting and checking validity of types  
- info Collecting page data  
[    ] - info Generating static pages (0/5)

Server Log
DATABASE_URL : https://hogehoge.com/database
API_KEY : 3KflaKDOQ0F
DEBUG_EMAIL : hogehoge@gmail.com
DEBUG_EMOJI : 👍
DEBUG_MESSAGE : HELLO SERVER
[=   ] - info Generating static pages (3/5)

Server Log
DATABASE_URL : https://hogehoge.com/database
API_KEY : 3KflaKDOQ0F
DEBUG_EMAIL : hogehoge@gmail.com
DEBUG_EMOJI : 👍
DEBUG_MESSAGE : HELLO SERVER
- info Generating static pages (5/5)
- info Finalizing page optimization  

Route (app)                                Size     First Load JS
┌ ○ /                                      141 B          77.7 kB
├ ○ /case-1                                141 B          77.7 kB
└ ○ /favicon.ico                           0 B                0 B
+ First Load JS shared by all              77.5 kB
  ├ chunks/14478101-08a82aad1ad550e2.js    50.5 kB
  ├ chunks/215-719eb731de1ca078.js         25.1 kB
  ├ chunks/main-app-2253954475def1ca.js    215 B
  └ chunks/webpack-47c83bed457c1f9b.js     1.64 kB

Route (pages)                              Size     First Load JS
─ ○ /404                                   182 B          75.4 kB
+ First Load JS shared by all              75.3 kB
  ├ chunks/framework-510ec8ffd65e1d01.js   45 kB
  ├ chunks/main-1b74ca39d3294f57.js        28.4 kB
  ├ chunks/pages/_app-3e277c1f911fda65.js  195 B
  └ chunks/webpack-47c83bed457c1f9b.js     1.64 kB

○  (Static)  automatically rendered as static HTML (uses no initial props)

実行します。

$ pnpm start

ページを表示するとファイルがダウンロードされます。今回は、サーバ側で全ての寄りが終わっているため、クライアント側にはサーバサイドの環境変数が漏洩することはありません。

ケース2:クライアントで環境変数を利用

クライアントとサーバサイドのスキーマを同一ファイルで定義しているスキーマファイル(env.mjs)を読み込み、環境変数を env からアクセスします。

$ mkdir -p src/app/case-2
$ touch src/app/case-2/page.tsx
src/app/case-2/page.tsx
"use client"

// クライアントとサーバサイドのスキーマを同一ファイルで定義しているファイルを読み込む
import { env } from "@/env.mjs";

export default function Home() {
  // スキーマをを読み込むことでタイプセーフに環境変数を扱える
  const nextPublicDebugMessage = env.NEXT_PUBLIC_DEBUG_MESSAGE;
  const nextPublicPublishableKey = env.NEXT_PUBLIC_PUBLISHABLE_KEY;

  // クライアントのログに出力される
  console.log("\n")
  console.log(`Client Log`)
  console.log(`NEXT_PUBLIC_DEBUG_MESSAGE : ${nextPublicDebugMessage}`);
  console.log(`NEXT_PUBLIC_PUBLISHABLE_KEY : ${nextPublicPublishableKey}`);

  return (
    <main className="text-lg">
      クライアント
    </main>
  );
}

ビルドし、実行します。

$ pnpm build
$ pnpm start

ページを表示するとファイルがダウンロードされます。

今回は、ファイルを開くと、スキーマがダウンロードされており、サーバサイドの環境変数の一覧が見えます。

ちなみに use client を利用しているので console.log はクライアント側のログに出力されます。

ケース3:クライアントで環境変数を利用(スキーマを分ける)

今度はサーバサイドとクライアントのスキーマを分けます。

$ mkdir -p src/app/case-3
$ touch src/app/case-3/page.tsx
src/app/case-3/page.tsx
"use client"

// クライアントとサーバサイドのスキーマを同一ファイルで定義しているファイルを読み込む
import { env } from "@/env/client.mjs";

export default function Home() {
  // スキーマをを読み込むことでタイプセーフに環境変数を扱える
  const nextPublicDebugMessage = env.NEXT_PUBLIC_DEBUG_MESSAGE;
  const nextPublicPublishableKey = env.NEXT_PUBLIC_PUBLISHABLE_KEY;

  // クライアントのログに出力される
  console.log("\n")
  console.log(`Client Log`)
  console.log(`NEXT_PUBLIC_DEBUG_MESSAGE : ${nextPublicDebugMessage}`);
  console.log(`NEXT_PUBLIC_PUBLISHABLE_KEY : ${nextPublicPublishableKey}`);

  return (
    <main className="text-lg">
      クライアント
    </main>
  );
}

ビルドし、実行します。

$ pnpm build
$ pnpm start

今回もスキーマはダウンロードされていますが、サーバーサイドのスキーマはダウンロードされていません。

コミットします。

コミット処理
$ pnpm build
$ git add .
$ git commit -m "created pages"

さいごに

  • T3-env[1:1] を利用し、Next.js で環境変数のタイプセーフに扱う方法を紹介しました。
  • スキーマファイルを同一ファイルにすることで開発の利便性は向上しますが、不用意にサーバ側の環境変数がクライアントに見えてしまいます。どのようなインフラで構築されているか、漏洩しても問題ないかを考慮して利用してください。
脚注
  1. https://env.t3.gg/ ↩︎ ↩︎

  2. https://zod.dev/ ↩︎

Discussion