🌏

Zod v4 単独でデフォルトメッセージを日本語化する

に公開

要点

  • 先日リリースされたZodのv4では本体の機能としてデフォルトメッセージのlocalizationができるようになった。
  • v3以前はスキーマのカスタムメッセージを書くか、自力でエラーマップファイルを書いて setErrorMap で渡す必要があった。
  • とはいえValidation内容によっては標準メッセージはイマイチなのでカスタムする必要はある。

💎 localization in 34 languages

https://x.com/colinhacks/status/1924484438052032849

やりかた

v4の公式ドキュメントの通りやってみた、というだけなのでドキュメント参照。
https://zod.dev/error-customization?id=internationalization#internationalization

インストール

https://zod.dev/v4

To simplify the migration process both for users and Zod's ecosystem of associated libraries, Zod 4 will initially published alongside Zod 3 as part of the zod@3.25 release. Despite the version number, it it considered stable and ready for production use.

現状v4はv3の一部として同梱されている形なので、 Zodのv3.25以上をインストールする。

実装と出力例

実装

z.config(ja()); するだけでOK。

import { z } from "zod/v4";
import ja from "zod/v4/locales/ja.js";

z.config(ja());

const UserSchema = z.object({
  id: z.number().positive(),
  name: z.string().min(1).max(50),
  email: z.email(),
  age: z.number().min(0).max(120).optional(),
  isActive: z.boolean(),
});

const userData = {
  id: -1,
  name: "",
  email: "invalid-email",
  age: 200,
  isActive: "true",
};

try {
  const user = UserSchema.parse(userData);
  console.log("ok", user);
} catch (error: unknown) {
  if (error instanceof z.ZodError) {
    for (const [index, err] of error.issues.entries()) {
      console.log(`${err.path.join(".")} : ${err.message} (${err.code})`);
    }
  }
}

出力

id : 小さすぎる値: numberは0>である必要があります (too_small)
name : 小さすぎる値: stringは1文字>である必要があります (too_small)
email : 無効なメールアドレス (invalid_format)
age : 大きすぎる値: numberは120<=である必要があります (too_big)
isActive : 無効な入力: booleanが期待されましたが、stringが入力されました (invalid_type)

その他のメッセージや対応言語はコード参照。
https://github.com/colinhacks/zod/tree/main/packages/zod/src/v4/locales

感想

2行追加するだけで日本語化できるのはとても楽。余計なライブラリも入らない。

メッセージ自体は、そのままで使えるものもあるが 「stringは1文字>である必要があります」とかは厳しい。
英語だと「expected string to have >1 characters」となって通じそうなメッセージだが、英単語から日本語への置換では文法的に限界がある。

仕事でデフォルトのまま使うことはなさそうだが、一応通じるので開発初期にとりあえず日本語化するにはよさそう。
...それなら英語のままでいい気もするが、知っておくと多少楽ができるかも。

Discussion