Next.js服务端zod-i18n校验错误信息始终为undefined
Zod + zod-i18n在Next.js服务端校验时错误消息message为undefined的原因及解决方法
问题复现
在Next.js的/pages/api/hello/index.ts中使用zod和zod-i18n做数据校验,客户端运行正常,但服务端校验后返回的错误对象中message字段为undefined,错误结构如下:
issues: [ { code: 'too_big', maximum: 30, type: 'string', inclusive: true, exact: false, message: undefined, path: [Array] } ]
原因分析
zod-i18n的国际化配置仅在客户端完成了初始化,但Next.js的服务端API路由是独立的执行环境,不会共享客户端的配置:
- 客户端通常会在入口文件(如
_app.tsx)中调用setErrorMap加载国际化消息资源,但服务端API路由不会执行这段代码。 - 服务端校验时,zod未被配置对应的错误映射,无法生成本地化的错误消息,因此
message字段为undefined。
解决方法
在服务端API路由中单独初始化zod-i18n的配置:
- 确保已安装依赖(若未安装):
npm install zod-i18n-map @intl-messageformat/core
- 在API路由文件开头添加初始化代码:
import { z } from 'zod'; import { setErrorMap } from 'zod'; import { zodI18nMap } from 'zod-i18n-map'; // 引入你需要的语言包,这里以中文为例 import zhLocale from 'zod-i18n-map/locales/zh.json'; // 初始化zod的错误映射 setErrorMap(zodI18nMap({ locales: { zh: zhLocale } })); // 你的原有校验代码 const params = { name: fields['company[name]'][0] }; const schema = z.object({ name: z.string().min(1).max(30), }); const validation = schema.safeParse(params); if (!validation.success) { console.log("issues", validation.error.issues); const errors: Record<string, string> = validation.error.issues.reduce( (acc, curr) => ({ ...acc, [`${curr.path.join('.')}`]: curr.message }), {}, ); return res.status(422).json({ errors }); }
- 多路由复用优化:
如果多个API路由都需要校验,可将初始化逻辑抽成公共模块:
// utils/zod-i18n.ts import { setErrorMap } from 'zod'; import { zodI18nMap } from 'zod-i18n-map'; import zhLocale from 'zod-i18n-map/locales/zh.json'; export const initZodI18n = () => { setErrorMap(zodI18nMap({ locales: { zh: zhLocale } })); };
然后在每个API路由中引入调用:
import { initZodI18n } from '../../../utils/zod-i18n'; initZodI18n(); // 后续校验代码...
内容的提问来源于stack exchange,提问作者Yusuke
相关产品推荐
相关产品推荐

