Jump to content

Attention: This page is 4 days older than the English version and might be outdated. If you're a native speaker of this language and would like to contribute to the project, please consider updating this page to match the latest English version.

You can also view the English version of this page.

Zmienne Środowiskowe

Create T3 App korzysta z paczki ZodÔćŚ w celu walidacji twoich zmiennych ┼Ťrodowiskowych podczas runtimeÔÇÖu oraz budowania aplikacji. Do┼é─ůczane s─ů z tego powodu dodatkowe narz─Ödzia w pliku src/env.mjs.

env.mjs

TLDR; Je┼╝eli chcesz doda─ç now─ů zmienn─ů ┼Ťrodowiskow─ů, musisz doda─ç j─ů zar├│wno do pliku .env, jak i zdefiniowa─ç jej walidator w pliku src/env.mjs.

Plik ten podzielony jest na dwie cz─Ö┼Ťci - schemat zmiennych i wykorzystywanie obiektu process.env, jak i logika walidacji. Logika ta nie powinna by─ç zmieniana.

env.mjs
const server = z.object({
  NODE_ENV: z.enum(["development", "test", "production"]),
});

const client = z.object({
  // NEXT_PUBLIC_CLIENTVAR: z.string(),
});

const processEnv = {
  NODE_ENV: process.env.NODE_ENV,
  // NEXT_PUBLIC_CLIENTVAR: process.env.NEXT_PUBLIC_CLIENTVAR,
};

Schemat Dla Serwera

Zdefiniuj tutaj zmienne ┼Ťrodowiskowe dla serwera.

Koniecznie nie prefixuj tutejszych kluczy NEXT_PUBLIC_, aby przypadkiem nie ujawni─ç ich do klienta.

Schemat Dla Klienta

Zdefiniuj tutaj zmienne ┼Ťrodowiskowe dla klienta.

Aby ujawni─ç zmienne dla klienta dodaj prefix NEXT_PUBLIC. Je┼╝eli tego nie zrobisz, walidacja nie zadzia┼éa, pomagaj─ůc ci w wykryciu niew┼éa┼Ťciwej konfiguracji.

Obiekt processEnv

Wykorzystaj destrukturyzacj─Ö obiektu process.env.

Potrzebny jest nam obiekt, kt├│ry parseÔÇÖowa─ç mo┼╝emy z naszymi schematami Zoda, a z powodu sposobu w jaki Next.js przetwarza zmienne ┼Ťrodowiskowe, nie mo┼╝esz destrukturyzowa─ç obiektu process.env tak jak zwyk┼éego obiektu - trzeba to zrobi─ç manualnie.

TypeScript zapewni poprawno┼Ť─ç destrukturyzacji obiektu i zapobiegnie sytuacji, w kt├│rej zapomnisz o jakim┼Ť kluczu.

// ÔŁî To nie zadzia┼éa, musimy r─Öcznie "rozbi─ç" `process.env`
const schema = z.object({
  NEXT_PUBLIC_WS_KEY: z.string(),
});

const validated = schema.parse(process.env);

Logika Walidacji

Dla zainteresowanego czytelnika:

Zaawansowane: Logika walidacji

W zale┼╝no┼Ťci od ┼Ťrodowiska (serwer lub klient) walidujemy albo oba schematy, albo tylko schemat klienta. Oznacza to, i┼╝ nawet je┼Ťli zmienne ┼Ťrodowiskowe serwera nie b─Öd─ů zdefiniowane, nie zostanie wyrzucony b┼é─ůd walidacji - mo┼╝emy wi─Öc mie─ç jeden punkt odniesienia do naszych zmiennych.

env.mjs
const isServer = typeof window === "undefined";

const merged = server.merge(client);
const parsed = isServer
  ? merged.safeParse(processEnv)  // <-- na serwerze, sprawd┼║ oba schematy
  : client.safeParse(processEnv); // <-- na kliencie, sprawd┼║ tylko zmienne klienta

if (parsed.success === false) {
  console.error(
    "ÔŁî Invalid environment variables:\n",
    ...formatErrors(parsed.error.format()),
  );
  throw new Error("Invalid environment variables");
}

Nast─Öpnie korzystamy z obiektu proxy, aby wyrzuca─ç b┼é─Ödy, je┼Ťli chcesz skorzysta─ç z serwerowych zmiennych ┼Ťrodowiskowych na kliencie.

env.mjs
// proxy pozwala na zmian─Ö gettera
export const env = new Proxy(parsed.data, {
  get(target, prop) {
    if (typeof prop !== "string") return undefined;
    // na kliencie pozwalamy jedynie na zmienne NEXT_PUBLIC_
    if (!isServer && !prop.startsWith("NEXT_PUBLIC_"))
      throw new Error(
        "ÔŁî Attempted to access serverside environment variable on the client",
      );
    return target[prop]; // <-- w przeciwnym razie, zwr├│─ç warto┼Ť─ç
  },
});

Korzystanie Ze Zmiennych Środowiskowych

Je┼╝eli chcesz skorzysta─ç ze swoich zmiennych ┼Ťrodowiskowych, mo┼╝esz zaimportowa─ç je z pliku env.mjs i skorzysta─ç z nich tak, jak normalnie by┼éoby to mo┼╝liwe. Je┼╝eli zaimportujesz obiekt ten na kliencie i spr├│bujesz skorzysta─ç ze zmiennych serwera, wyst─ůpi b┼é─ůd runtime.

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

// `env` jest w pełni typesafe i zapewnia autouzupełnianie
const dbUrl = env.DATABASE_URL;
pages/index.tsx
import { env } from "../env.mjs";

// ÔŁî Wyrzuci to b┼é─ůd runtime
const dbUrl = env.DATABASE_URL;

// Ôťů To jest ok
const wsKey = env.NEXT_PUBLIC_WS_KEY;

.env.example

Poniewa┼╝ plik .env nie jest wrzucany na system kontroli wersji, do┼é─ůczamy tak┼╝e plik .env.example, w kt├│rym - jesli chcesz - mo┼╝esz zawrze─ç kopi─Ö pliku .env z usuni─Ötymi secretami. Nie jest to wymagane, jednak polecamy trzyma─ç aktualn─ů kopi─Ö przyk┼éadowego pliku, aby u┼éatwi─ç potencjalnym kontrybutorom rozpocz─Öcie pracy w ich ┼Ťrodowisku.

Niekt├│re frameworki i narz─Ödzia do budowania, takie jak Next.js, zalecaj─ů przechowywanie sekretnych warto┼Ťci w pliku .env.local i commitowanie plik├│w .env do projektu. Nie jest to przez nas jednak rekomendowane, poniewa┼╝ mo┼╝e to ┼éatwo prowadzi─ç do przypadkowego ujawnienia tych warto┼Ťci. Polecamy natomiast przechowywanie sekretnych warto┼Ťci w pliku .env, trzymanie pliku tego w .gitignore i commitowanie jedynie plik├│w .env.example.

Dodawanie Zmiennych Środowiskowych

Aby upewni─ç si─Ö, ┼╝e tw├│j projekt nie zbuduje si─Ö bez wymaganych zmiennych ┼Ťrodowiskowych, b─Ödziesz musia┼é doda─ç now─ů zmienn─ů w dw├│ch miejscach:

­čôä .env: Wprowad┼║ swoj─ů zmienn─ů ┼Ťrod. tak, jak to zwykle robisz (np. KLUCZ=WARTO┼Ü─ć)

­čôä env.mjs: Dodaj odpowiadaj─ůc─ů jej logik─Ö walidacji definiuj─ůc schemat Zod, np. KLUCZ: z.string(). Nast─Öpnie wykorzystaj obiekt process.env w processEnv, np. KEY: process.env.KEY.

Opcjonalnie mo┼╝esz zaktualizowa─ç plik .env.example:

­čôä .env.example: Wprowad┼║ swoj─ů zmienn─ů ┼Ťrodowiskow─ů, upewnij si─Ö jednak ┼╝e nie nie posiada ona warto┼Ťci, kt├│ra jest sekretna, np. KLUCZ=WARTO┼Ü─ć lub KLUCZ=

Przykład

Chc─Ö doda─ç m├│j token do API Twittera jako zmienn─ů ┼Ťrodowiskow─ů po stronie serwera

  1. Dodaj zmienn─ů ┼Ťrod. do pliku .env:
TWITTER_API_TOKEN=1234567890
  1. Dodaj zmienn─ů ┼Ťrodowiskow─ů do pliku env.mjs:
export const server = z.object({
  // ...
  TWITTER_API_TOKEN: z.string(),
});

export const processEnv = {
  // ...
  TWITTER_API_TOKEN: process.env.TWITTER_API_TOKEN,
};

UWAGA: Pusty string to dalej string, wi─Öc z.string() zaakceptuje ka┼╝dy pusty tekst jako poprawn─ů warto┼Ť─ç. Je┼╝eli chcesz, by warto┼Ť─ç by┼éa wymagana (i nie pusta!), mo┼╝esz u┼╝y─ç z.string().min(1).

  1. opcjonalnie: Dodaj zmienn─ů ┼Ťrodowiskow─ů do .env.example. Usu┼ä jednak token.
TWITTER_API_TOKEN=

Recent Contributors To This Page