これは「react-jsonschema-formのカレンダー | Advent Calendar 2023 - Qiita」の11日目の記事です。
今回は、react-jsonschema-form (RJSF) にて、バリデーションのエラーメッセージをローカライズしてみます。
目次
環境
- react-jsonschema-form 5.15.0
- React 18.2.0
- React Router 6.20.1
- ajv-i18n 4.2.0
RJSFのバリデーションエラーメッセージのローカライズについて
RJSFのバリデーションでは、
- Ajv 8 のvalidatorを使っている
- Ajv8 では
ajv-18n
を使ってローカライズしている
より、RJSFでもローカライズが可能です。
Validation | react-jsonschema-form
ただ、RJSFとは別に ajv-i18n
をインストールする必要があります。
# インストール $ npm install ajv-i18n added 5 packages, removed 4 packages, changed 2 packages, and audited 297 packages in 3s 55 packages are looking for funding run `npm fund` for details 1 moderate severity vulnerability To address all issues, run: npm audit fix Run `npm audit` for details. # moderate severity vulnerabilityが表示されたので、画面に表示されたコマンドを実行 $ npm audit fix changed 2 packages, and audited 297 packages in 2s 55 packages are looking for funding run `npm fund` for details found 0 vulnerabilities
ajv-i18nにおける、日本語の対応状況
ajv-i18nのリポジトリにあるREADMEには、localeごとの対応状況が記載されています。
https://github.com/ajv-validator/ajv-i18n
これによると、日本語の場合 JSON Schema draft 4
までサポートしているようでした。
ajv-i18nがJSON Schema draft 4 サポートだとしたら、RJSFではどのように表示されるか気になりました。
そこで、
- draft 4 に対応している
minimum
- draft 6 で対応している
const
の入力項目を用意して動作を確認してみます。
import {RJSFSchema} from "@rjsf/utils"; import Form from "@rjsf/mui"; import {customizeValidator} from "@rjsf/validator-ajv8"; import localizer from 'ajv-i18n' // npm installが必要 export const NotExistsLocalizerForm = () => { const schema: RJSFSchema = { title: "Not Exists Localizer Form", type: "object", required: [], properties: { stringInput: { type: "string", const: "りんご" }, integerInput: { type: "integer", minimum: 100 } } } const validator = customizeValidator({}, localizer.ja) return ( <div style={{width: '400px'}}> <Form schema={schema} validator={validator} noHtml5Validate /> </div> ) }
その結果、
- minimumは日本語化された
- constは日本語化されず、英語となった
となりました。
JSON Schema draft 6以降のメッセージを日本語化する
JSON Schema draft 6以降のメッセージだけが英語というのも見栄えが良くないので、日本語化する方法を探してみます。
まず、 avj-i18n
の実装を見たところ、翻訳データは以下のファイルに記載されていました。
https://github.com/ajv-validator/ajv-i18n/blob/master/messages/index.js
このファイルについて、 localizeディレクトリにあるREADMEを見ると
This folder contains compiled localization functions.
Do not edit *.js files directly, edit JSON Schema messages in messages/index.js and JSON Type Definition messages in messages/jtd.js.
If this folder doesn't have any locale sub-folders, run npm run build.
https://github.com/ajv-validator/ajv-i18n/tree/master/localize
とあったことから、自分でカスタマイズしたものを導入するのは難しそうでした。
そこで、日本語化する方法としては以下の2つが考えてみました。
- 自分でlocalizerを作る
- バリデーションのエラーメッセージを変更する
自分でlocalizerを作る
まずは、RJSFのLocalization (L12n) supportページにあった、自分でlocalizerを作る方法をためします。
https://rjsf-team.github.io/react-jsonschema-form/docs/usage/validation/#localization-l12n-support
最初に、const
だけメッセージを差し替える localizer
を作ります。
const localizer = (errors: null | ErrorObject[] = []) => { if (!(errors && errors.length)) return; errors.forEach(function (error) { let outMessage = '' switch (error.keyword) { case 'const': { outMessage = "指定した文字を入力してください" break } default: { outMessage = error.message.toString() } } error.message = outMessage }) }
続いて、 customizeValidator
関数を使ってvalidatorを生成し、Formのpropsに渡します。
const validator = customizeValidator({}, localizer) return ( <div style={{width: '400px'}}> <Form schema={schema} validator={validator} noHtml5Validate /> </div> )
動かしてみたところ、
const
のエラーメッセージは日本語に差し替わったminimum
のエラーメッセージは英語になった
となりました。
RJSFのドキュメントに
You must process all the cases which you need by yourself.
とあった通り、自分でlocalizerを作る場合はすべてのキーを用意する必要があるようです。
バリデーションのエラーメッセージを変更する
もう一つは、バリデーションのエラーメッセージを変更する方法です。
これは10日目でふれた、Formのprops transformErrors
を使う方法です。
今回は、 error.name === "const"
のときに、エラーメッセージを差し替える関数を用意します。
const transformErrors = (errors: RJSFValidationError[], _uiSchema: typeof schema) => { return errors.map((error) => { if (error.name === "const") { error.message = "指定した文字を入力してください" error.stack = "[Stack] 指定した文字を入力してください" } return error }) }
あとは、この関数と customizeValidator
で生成したvalidatorをFormに渡します。
const validator = customizeValidator({}, localizer.ja) return ( <div style={{width: '400px'}}> <Form schema={schema} validator={validator} transformErrors={transformErrors} noHtml5Validate /> </div> )
動かしてみたところ、
const
のエラーメッセージはtransformErrors
由来minimum
のエラーメッセージはlocalizer.ja
由来
となり、両方のメッセージとも日本語化されました。
ソースコード
Githubにあげました。
https://github.com/thinkAmi-sandbox/rjsf_advent_calendar_2023
今回のプルリクはこちら。
https://github.com/thinkAmi-sandbox/rjsf_advent_calendar_2023/pull/10