Jump to content

Змінні середовища

Create T3 App використовує власний пакет @t3-oss/env-nextjs разом із Zod для валідації змінних середовища під час виконання та під час збирання, надаючи просту логіку у файлі src/env.js:

env.js

TLDR; Якщо ви хочете додати нову змінну середовища, вам слід додати валідатор до src/env.js, а потім пару ключ-значення в .env.

env.js
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";

export const env = createEnv({
  server: {
    NODE_ENV: z.enum(["development", "test", "production"]),
  },
  client: {
    // NEXT_PUBLIC_CLIENTVAR: z.string(),
  },
  runtimeEnv: {
    NODE_ENV: process.env.NODE_ENV,
  },
});

T3 Env використовує createEnv, який відповідає за створення схеми і буде включати головну логіку валідації для клієнтських і серверних змінних середовища.

ℹ️

Для отримання додаткової інформації про те, як createEnv працює зсередини, подивіться документацію T3 Env (EN)

Використання змінних середовища

Коли ви хочете використовувати змінні середовища, ви можете імпортувати їх із env.js і використовувати їх так, як ви зазвичай використовували б. Якщо ви імпортуєте цей файл на стороні клієнта і спробуєте отримати серверну змінну, ви отримаєте помилку виконання:

pages/api/hello.ts
import { env } from "../../env.js";

// `env` is fully typesafe and provides autocompletion
const dbUrl = env.DATABASE_URL;
pages/index.tsx
import { env } from "../env.js";

// ❌ This will throw a runtime error
const dbUrl = env.DATABASE_URL;

// ✅ This is fine
const wsKey = env.NEXT_PUBLIC_WS_KEY;

.env.example

Через те, що файл .env за замовчуванням не додається до системи контролю версій, ми також додали файл .env.example, в якому ви можете за бажанням зберегти копію вашого файлу .env з видаленими secrets. Це необов’язково, але ми рекомендуємо тримати приклад в актуальному стані, щоб зробити процес налаштування середовища для нових учасників проекту якомога простішим.

Деякі фреймворки та інструменти збірки, такі як Next.js, пропонують зберігати secrets у файлі .env.local і коммітити файли .env у ваш проект. Це не рекомендується, оскільки це може полегшити випадковий комміт secrets у ваш проект. Натомість ми рекомендуємо зберігати secrets в .env, тримати ваш файл .env в .gitignore і коммітити лише файли .env.example у ваш проект.

Додавання змінних середовища

Для того, щоб переконатися, що ваша збірка ніколи не завершиться без змінних середовища, які проєкт вимагає, вам потрібно додати нові змінні середовища в двох місцях:

📄 .env: Введіть змінну середовища, як зазвичай робите у файлі .env, тобто KEY=VALUE

📄 env.js: Додайте відповідну логіку валідації для змінних середовища, визначивши для кожної з них Zod схему всередині createEnv, наприклад KEY: z.string(). Крім цього, переконайтеся в тому, що ви деструктурували їх в опції runtimeEnv, наприклад KEY: process.env.KEY.

ℹ️

Навіщо потрібно деструктурувати змінні середовища всередині runtimeEnv? Це пов’язано з тим, як Next.js збирає змінні середовища в деяких рантаймах. Деструктуруючи їх вручну, ми гарантуємо, що ці змінні не будуть прибрані з фінальної збірки.

Опціонально, ви також можете оновлювати файл .env.example:

📄 .env.example: Введіть вашу змінну середовища, але переконайтеся, що не включаєте значення, якщо воно є секретним, тобто KEY=VALUE або KEY=.

Приклад

Я хочу додати мій Twitter API токен як змінну середовища на стороні сервера

  1. Додайте змінну середовища в .env:
TWITTER_API_TOKEN=1234567890
  1. Додайте змінну середовища в env.js:
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";

export const env = createEnv({
  server: {
    TWITTER_API_TOKEN: z.string(),
  },
  // ...
  runtimeEnv: {
    // ...
    TWITTER_API_TOKEN: process.env.TWITTER_API_TOKEN,
  },
});
  1. Опціонально: Додайте змінну середовища в .env.example, але не включайте токен в runtimeEnv.
TWITTER_API_TOKEN=

Type Coercion

Усі змінні які ви додаєте до .env будуть импортовані як рядки, навіть якщо їх значення має представляти інший тип. Якщо ви хочете використовувати ваші змінні середовища як інший тип під час рантайму, ви можете використовувати coerce з Zod для конвертації рядків в тип, який ви хочете. Це викине помилку, якщо конвертація не вдасться.

Додайте змінну до вашого .env:

SOME_NUMBER=123
SOME_BOOLEAN=true

Потім, провалідуйте їх в env.js:

import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";

export const env = createEnv({
  server: {
    SOME_NUMBER: z.coerce.number(),
    SOME_BOOLEAN: z.coerce.boolean(),
  },
  // ...
  runtimeEnv: {
    SOME_NUMBER: process.env.SOME_NUMBER,
    SOME_BOOLEAN: process.env.SOME_BOOLEAN,
  },
});