You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 13中使用"use client"时Zod环境变量验证失效

解决Next.js 13客户端组件中Zod环境变量验证失效问题

问题根源

你遇到的核心问题在于:

  1. 客户端组件(加了"use client")只能访问以NEXT_PUBLIC_开头的环境变量,像JWT_SECRET这类敏感变量在客户端环境中根本不存在。
  2. 你把公开变量和私有变量放在同一个Zod Schema里解析,当客户端组件导入这个Schema时,Zod会尝试验证所有字段——包括客户端拿不到的JWT_SECRET,直接导致验证失败。

解决方案

方案一:拆分客户端/服务端环境变量Schema

把环境变量按使用场景拆分,避免客户端验证服务端专属变量:

// src/utils/env.ts
import { z } from "zod";

// 仅客户端可用的公开环境变量Schema
export const clientEnv = z.object({
  NEXT_PUBLIC_APIAUTH: z.string().min(1),
}).parse({
  NEXT_PUBLIC_APIAUTH: process.env.NEXT_PUBLIC_APIAUTH,
});

// 服务端可用的全量环境变量Schema
export const serverEnv = z.object({
  NEXT_PUBLIC_APIAUTH: z.string().min(1),
  JWT_SECRET: z.string().min(1),
}).parse(process.env);

然后在对应场景导入:

// src/app/signup/page.tsx(客户端组件)
"use client";
import { clientEnv } from "@/utils/env";

console.log(clientEnv.NEXT_PUBLIC_APIAUTH); // 正常输出

服务端代码(如app/api目录下的文件)则导入serverEnv来使用JWT_SECRET。

方案二:根据运行环境动态解析Schema

如果不想拆分Schema,可以通过判断环境来选择性验证字段:

// src/utils/env.ts
import { z } from "zod";

// 判断当前是否为服务端环境
const isServer = typeof window === "undefined";

// 基础公开变量Schema
const baseSchema = z.object({
  NEXT_PUBLIC_APIAUTH: z.string().min(1),
});

// 服务端追加私有变量Schema
const serverSchema = baseSchema.extend({
  JWT_SECRET: z.string().min(1),
});

// 根据环境选择解析逻辑
export const env = isServer 
  ? serverSchema.parse(process.env) 
  : baseSchema.parse(process.env);

这样客户端只会验证NEXT_PUBLIC_APIAUTH,服务端会验证全量变量,不会出现报错。

关键注意事项

  • 确保.env.local中的公开变量确实以NEXT_PUBLIC_开头,拼写不能出错。
  • 敏感变量(如JWT_SECRET)绝对不能在客户端组件中使用或解析,否则会直接泄露给用户。

内容的提问来源于stack exchange,提问作者Neeraj Walia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 15:27:01