Customization
Below are some examples of how you can customize the behavior of the library. The default values are shown in the snippets below.
Skipping validation
Skipping validation is not encouraged and will lead to your types and runtime values being out of sync. It is available to let you opt out of validation during linting (or similar), or if you're building with Docker and not all environment variables are present when building the image.
import { createEnv } from "@t3-oss/env-core";
export const env = createEnv({
// ...
// Tell the library to skip validation if condition is true.
skipValidation: false,
});
import { createEnv } from "@t3-oss/env-core";
export const env = createEnv({
// ...
// Tell the library to skip validation if condition is true.
skipValidation: false,
});
Overriding the default error handler
import { createEnv } from "@t3-oss/env-core";
export const env = createEnv({
// ...
// Called when the schema validation fails.
onValidationError: (error: ZodError) => {
console.error(
"❌ Invalid environment variables:",
error.flatten().fieldErrors
);
throw new Error("Invalid environment variables");
},
// Called when server variables are accessed on the client.
onInvalidAccess: (variable: string) => {
throw new Error(
"❌ Attempted to access a server-side environment variable on the client"
);
},
});
import { createEnv } from "@t3-oss/env-core";
export const env = createEnv({
// ...
// Called when the schema validation fails.
onValidationError: (error: ZodError) => {
console.error(
"❌ Invalid environment variables:",
error.flatten().fieldErrors
);
throw new Error("Invalid environment variables");
},
// Called when server variables are accessed on the client.
onInvalidAccess: (variable: string) => {
throw new Error(
"❌ Attempted to access a server-side environment variable on the client"
);
},
});
Tell when we're in a server context
import { createEnv } from "@t3-oss/env-core";
export const env = createEnv({
// ...
// Tell the library when we're in a server context.
isServer: typeof window === "undefined",
});
import { createEnv } from "@t3-oss/env-core";
export const env = createEnv({
// ...
// Tell the library when we're in a server context.
isServer: typeof window === "undefined",
});
If you want to reuse above isServer
check in multiple places, you can use the shared
section.
Treat empty strings as undefined
By default, T3 Env will feed the environment variables directly to the Zod validator. This means that if you have an empty string for a value that is supposed to be a number (e.g. PORT=
in a ".env" file), Zod will flag
it as a type mismatch violation. Additionally, if you have an empty string for a value that is supposed to be a string with a default value (e.g. DOMAIN=
in an ".env" file), the default value will never be applied. In order to solve these issues, you can set theemptyStringAsUndefined
option totrue
.
import { createEnv } from "@t3-oss/env-core";
export const env = createEnv({
// ...
// Treat empty strings as undefined.
emptyStringAsUndefined: false,
});
import { createEnv } from "@t3-oss/env-core";
export const env = createEnv({
// ...
// Treat empty strings as undefined.
emptyStringAsUndefined: false,
});
Extending presets
Your env object may extend other presets by using the extends
property. This can be used to include system environment variables for your deployment provider, or if you have a monorepo with multiple packages that share some environment variables.
import { createEnv } from "@t3-oss/env-core";
import { vercel } from "@t3-oss/env-core/presets";
export const env = createEnv({
// ...
// Extend the Vercel preset.
extends: [vercel()],
});
env.VERCEL_URL; // string
import { createEnv } from "@t3-oss/env-core";
import { vercel } from "@t3-oss/env-core/presets";
export const env = createEnv({
// ...
// Extend the Vercel preset.
extends: [vercel()],
});
env.VERCEL_URL; // string
T3 Env ships the following presets out of the box, all importable from the /presets
entrypoint.
vercel
- Vercel environment variables. See full list here.uploadthing
- All environment variables required to use UploadThing. More info here.render
- Render environment variables. See full list here.railway
- Railway provided system environment variables. See full list here.
Feel free to open a PR with more presets!
A preset is just like any other env object, so you can easily create your own:
// packages/auth/env.ts
import { createEnv } from "@t3-oss/env-core";
export const env = createEnv({
// ...
});
// apps/web/env.ts
import { createEnv } from "@t3-oss/env-nextjs";
import { env as authEnv } from "@repo/auth/env";
export const env = createEnv({
// ...
extends: [authEnv],
});
// packages/auth/env.ts
import { createEnv } from "@t3-oss/env-core";
export const env = createEnv({
// ...
});
// apps/web/env.ts
import { createEnv } from "@t3-oss/env-nextjs";
import { env as authEnv } from "@repo/auth/env";
export const env = createEnv({
// ...
extends: [authEnv],
});