SvelteKit × SuperFormsでValibotのバリデーションエラーを日本語化する方法
はじめに
SvelteKitでフォームを実装する際、Superformsは非常に便利なライブラリです。さらにバリデーションライブラリとしてValibotを使用することで、型安全なバリデーションを実現できます。しかし、デフォルトのエラーメッセージは英語のため、日本語アプリケーションでは使いづらい場合があります。本記事では、SuperformsとValibotを使用して、エラーメッセージを日本語化する方法を解説します。
想定読者
- SvelteKitでフォーム実装中の開発者
- SuperFormsのカスタマイズに興味がある方
前提条件
- SvelteKitプロジェクトが初期設定済み
- 以下のパッケージがインストール済み:
npm install sveltekit-superforms valibot
必要なパッケージのインストール
まず、Valibotのi18nパッケージをインストールします。
npm install @valibot/@i18n
翻訳ファイルの読み込み
プロジェクトのエントリーポイント(通常はsrc/routes/+layout.svelte
)で、日本語の翻訳ファイルを読み込みます。
import "@valibot/i18n/ja";
Superformsの設定
クライアントとサーバーサイド両方で同じスキーマを使用して、バリデーションを通すことを前提として説明します。
簡単なサンプルを示しますが、環境に合わせて適宜パス等は変えてください。
スキーマ定義
Superformsで使用するValibotのスキーマに、言語設定を追加します。
クライアントとサーバーサイドで同じスキーマを使用するので、どちらからも参照できるファイルパスに定義しています。
import { object, string, email, pipe, nonEmpty } from "valibot";
export const userSchema = object({
name: pipe(string(), nonEmpty()),
email: pipe(string(), nonEmpty(), email()),
});
クライアント・サーバーサイドでスキーマを設定
Superformsで使用するValibotのスキーマに、言語設定を追加します。
言語設定を行っている{ config: { lang: "ja" }
の部分がポイントです。
クライアントサイド
<script lang="ts">
import { superForm } from "sveltekit-superforms";
import { valibot } from "sveltekit-superforms/adapters";
import { userSchema } from "$lib/valibotSchema/schema";
const { data } = $props();
// Client API:
const { form, errors, enhance } = superForm(data.form, {
validators: valibot(userSchema, { config: { lang: "ja" } }),
});
</script>
サーバーサイド
Superformsで使用するValibotのスキーマに、言語設定を追加します。
言語設定を行っている{ config: { lang: "ja" }
の部分がポイントです。
export const actions = {
default: async ({ request }) => {
const form = await superValidate(
request,
valibot(userSchema, { config: { lang: "ja" } }),
{
errors: true,
},
);
if (!form.valid) {
return fail(400, { form });
}
// 後続処理...
},
};
これでデフォルトのバリデーションエラーメッセージを日本語化することができました。
(エラーメッセージの日本語の分かりやすさは何とも言えませんが・・・)
まとめ
以上で、SuperformsとValibotを使用した日本語エラーメッセージの実装が完了しました。この設定により、ユーザーフレンドリーなフォームバリデーションを実現できます。さらにカスタマイズしたい場合は、Valibotのドキュメントを参照して、独自のエラーメッセージを定義することも可能です。
valibotの引数に毎回、言語設定を入れる必要があるので冗長ではありますが、調べた限りこのような書き方をするしかなさそうでした。
(毎回、言語設定を書かずに実現する方法知っている方がいらっしゃいましたら教えてください。)
Discussion