Blueprint: lib/env.ts
Copy to apps/web/lib/env.ts. All environment access in the frontend MUST go through this module.
import { z } from "zod"
const serverSchema = z.object({ API_URL: z.url(), API_JWT_SECRET: z.string().min(32), AUTH_SECRET: z.string().min(32),})
const clientSchema = z.object({ NEXT_PUBLIC_APP_URL: z.url(),})
function parseEnv<T extends z.ZodTypeAny>(schema: T, source: Record<string, string | undefined>) { const result = schema.safeParse(source) if (!result.success) { throw new Error(`Invalid environment: ${result.error.message}`) } return result.data}
export const serverEnv = parseEnv(serverSchema, { API_URL: process.env.API_URL, API_JWT_SECRET: process.env.API_JWT_SECRET, AUTH_SECRET: process.env.AUTH_SECRET,})
export const clientEnv = parseEnv(clientSchema, { NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,})// BAD: direct process.env access outside lib/env.tsconst url = process.env.API_URLSee docs/conventions/frontend/environment-and-runtime-config.md.