LaravelでWebアプリケーションやお問い合わせフォーム、会員登録機能などを開発する際、避けて通れないのが入力バリデーション(入力値検証)です。
Laravelのバリデーションは非常に多機能で強力ですが、初期状態(デフォルト)のままではエラーメッセージがすべて英語(例:The email field is required. など)で表示されてしまいます。日本国内向けのサービスでは、ユーザーに分かりやすい日本語メッセージ(例:メールアドレスは必須項目です。)へ変更することが必須です。
しかし、
- 「Laravel 10やLaravel 11 / 12で言語ファイル(lang)の置き場所がどう変わったのか分からない」
- 「エラーメッセージは日本語になったが、項目名(フィールド名)が英語のまま残ってしまう」
- 「FormRequestやコントローラーごとに特定のメッセージだけを上書き・カスタマイズしたい」
といった疑問を持つ方も多いのではないでしょうか。
- 【3ステップで完了】ロケール設定から日本語言語ファイルの導入、項目名設定までの全手順
- Laravel 10 / 11 / 12 のディレクトリ構造の違いと
php artisan lang:publishコマンド - 実務ですぐ使える
lang/ja/validation.phpの日本語化定義コード&主要フォーム属性名(attributes)早見表 - FormRequestやControllerで個別にエラーメッセージ・属性名を上書きする方法
- Bladeテンプレートでの洗練されたエラーメッセージ表示方法
- 「日本語化が反映されない」ときの原因と解決チェックリスト
1. Laravelバリデーション日本語化の全体フロー(3ステップ)
Laravelのバリデーションメッセージを完全な日本語にするには、以下の3つのステップを順番に実行します。
- ステップ1:アプリケーションのロケール(locale)を日本語(ja)に設定する
(.env または config/app.php でAPP_LOCALE=jaを指定) - ステップ2:日本語用の言語ファイル(validation.php)を配置する
(lang/ja/validation.phpを作成・公開し、各種ルールの日本語文言を定義) - ステップ3:フォーム項目名(attributes)の日本語マッピングを設定する
(name→ 「お名前」、email→ 「メールアドレス」などの変換設定)
この3つを設定することで、The email field is required. から メールアドレス は必須項目です。 へと完璧に日本語化されます。それでは1つずつ見ていきましょう。
2. 【ステップ1】ロケール(locale)を日本語に設定する
まずはLaravelアプリケーション全体のデフォルト言語を日本語(ja)に切り替えます。
.env ファイルの編集(推奨)
Laravelでは環境変数 .env を使ってロケールとタイムゾーンを設定するのが標準的です。
# .env
APP_LOCALE=ja
APP_FALLBACK_LOCALE=ja
APP_FAKER_LOCALE=ja_JP
APP_TIMEZONE=Asia/Tokyo
config/app.php の確認(Laravel 10以前または明示的設定)
config/app.php 内の設定項目も確認しておきましょう(Laravel 11以降で config ディレクトリを公開している場合も含みます)。
// config/app.php
'timezone' => env('APP_TIMEZONE', 'Asia/Tokyo'),
'locale' => env('APP_LOCALE', 'ja'),
'fallback_locale' => env('APP_FALLBACK_LOCALE', 'ja'),
'faker_locale' => env('APP_FAKER_LOCALE', 'ja_JP'),
fallback_locale は、指定されたロケール(ja)に対応する翻訳ファイルや文言が見つからなかった際に、代替として使用される言語です。通常は en または ja を指定します。
3. 【ステップ2】日本語言語ファイル(validation.php)の導入
Laravelのバージョンによる言語ディレクトリの違い
Laravelのバージョンによって言語ファイルの配置場所が異なります。
| Laravel バージョン | 言語ファイルの配置パス |
|---|---|
| Laravel 10 / 11 / 12 | lang/ja/validation.php(プロジェクト直下) |
| Laravel 9 以前 | resources/lang/ja/validation.php |
言語ファイル公開コマンド(lang:publish)
Laravel 10以降のクリーンインストールでは、デフォルトで lang ディレクトリが存在しない場合があります。その場合は以下のArtisanコマンドを実行して公開します。
php artisan lang:publish
これによりプロジェクトルートに lang/en/ ディレクトリ(auth.php, pagination.php, passwords.php, validation.php)が作成されます。
日本語用ディレクトリと validation.php の作成
lang ディレクトリ配下に ja フォルダを作成し、その中に validation.php を配置します。
# Linux / macOS の場合
mkdir -p lang/ja
touch lang/ja/validation.php
コミュニティでメンテナンスされている
laravel-lang/lang パッケージを利用すると、世界中の言語ファイル(日本語含む)を簡単に一括導入できます。composer require laravel-lang/lang --devphp artisan lang:add ja本記事では外部パッケージに依存せず、プロジェクト単体で完結・自由に変更できるコード例を次に掲載します。
コピペで使える!lang/ja/validation.php 完全テンプレート
実務で頻出するバリデーションルールを日本語化したテンプレートコードです。lang/ja/validation.php にそのままコピーして使用できます。
<?php
return [
/*
|--------------------------------------------------------------------------
| バリデーション言語行
|--------------------------------------------------------------------------
|
| 以下の言語行は、バリデータクラスによって使用されるデフォルトのエラー
| メッセージを含んでいます。サイズルールなどの一部のルールには複数の
| バージョンがあります。必要に応じて自由に変更してください。
|
*/
'accepted' => ':attribute を承認してください。',
'accepted_if' => ':other が :value の場合、:attribute を承認してください。',
'active_url' => ':attribute は有効なURLではありません。',
'after' => ':attribute には :date より後の日付を指定してください。',
'after_or_equal' => ':attribute には :date 以降の日付を指定してください。',
'alpha' => ':attribute にはアルファベットのみ使用できます。',
'alpha_dash' => ':attribute には英数字、ハイフン(-)、アンダースコア(_)のみ使用できます。',
'alpha_num' => ':attribute には英数字のみ使用できます。',
'array' => ':attribute には配列を指定してください。',
'ascii' => ':attribute には半角英数字と記号のみ使用できます。',
'before' => ':attribute には :date より前の日付を指定してください。',
'before_or_equal' => ':attribute には :date 以前の日付を指定してください。',
'between' => [
'array' => ':attribute の項目数は :min 個から :max 個にしてください。',
'file' => ':attribute のファイルサイズは :min KBから :max KBにしてください。',
'numeric' => ':attribute は :min から :max の数値を入力してください。',
'string' => ':attribute は :min 文字から :max 文字で入力してください。',
],
'boolean' => ':attribute には true または false を指定してください。',
'can' => ':attribute に不正な値が含まれています。',
'confirmed' => ':attribute と確認用の入力が一致しません。',
'contains' => ':attribute に必要な値が含まれていません。',
'current_password' => 'パスワードが正しくありません。',
'date' => ':attribute には正しい日付を指定してください。',
'date_equals' => ':attribute には :date と同じ日付を指定してください。',
'date_format' => ':attribute の形式は :format と一致していません。',
'decimal' => ':attribute は小数点以下 :decimal 桁で指定してください。',
'declined' => ':attribute を拒否してください。',
'declined_if' => ':other が :value の場合、:attribute を拒否してください。',
'different' => ':attribute には :other と異なる値を指定してください。',
'digits' => ':attribute は :digits 桁の数字で入力してください。',
'digits_between' => ':attribute は :min 桁から :max 桁の数字で入力してください。',
'dimensions' => ':attribute の画像サイズが無効です。',
'distinct' => ':attribute に重複した値が存在します。',
'doesnt_end_with' => ':attribute は [:values] のいずれかで終わってはなりません。',
'doesnt_start_with' => ':attribute は [:values] のいずれかで始まってはなりません。',
'email' => ':attribute には有効なメールアドレス形式を入力してください。',
'ends_with' => ':attribute は [:values] のいずれかで終わる必要があります。',
'enum' => '選択された :attribute は正しくありません。',
'exists' => '選択された :attribute は存在しません。',
'extensions' => ':attribute には [:values] の拡張子のファイルを指定してください。',
'file' => ':attribute にはファイルを指定してください。',
'filled' => ':attribute に値を入力してください。',
'gt' => [
'array' => ':attribute の項目数は :value 個より多くしてください。',
'file' => ':attribute のファイルサイズは :value KBより大きくしてください。',
'numeric' => ':attribute は :value より大きい数値を入力してください。',
'string' => ':attribute は :value 文字より多く入力してください。',
],
'gte' => [
'array' => ':attribute の項目数は :value 個以上にしてください。',
'file' => ':attribute のファイルサイズは :value KB以上にしてください。',
'numeric' => ':attribute は :value 以上の数値を入力してください。',
'string' => ':attribute は :value 文字以上で入力してください。',
],
'hex_color' => ':attribute には有効な16進数カラーコードを指定してください。',
'image' => ':attribute には画像ファイル(jpg, png, bmp, gif, svg, webp)を指定してください。',
'in' => '選択された :attribute は無効です。',
'in_array' => ':attribute は :other に存在しません。',
'integer' => ':attribute には整数を入力してください。',
'ip' => ':attribute には有効なIPアドレスを入力してください。',
'ipv4' => ':attribute には有効なIPv4アドレスを入力してください。',
'ipv6' => ':attribute には有効なIPv6アドレスを入力してください。',
'json' => ':attribute には有効なJSON文字列を入力してください。',
'list' => ':attribute はリスト形式である必要があります。',
'lowercase' => ':attribute は小文字で入力してください。',
'lt' => [
'array' => ':attribute の項目数は :value 個未満にしてください。',
'file' => ':attribute のファイルサイズは :value KB未満にしてください。',
'numeric' => ':attribute は :value 未満の数値を入力してください。',
'string' => ':attribute は :value 文字未満で入力してください。',
],
'lte' => [
'array' => ':attribute の項目数は :value 個以下にしてください。',
'file' => ':attribute のファイルサイズは :value KB以下にしてください。',
'numeric' => ':attribute は :value 以下の数値を入力してください。',
'string' => ':attribute は :value 文字以下で入力してください。',
],
'mac_address' => ':attribute には有効なMACアドレスを指定してください。',
'max' => [
'array' => ':attribute の項目数は :max 個以下にしてください。',
'file' => ':attribute のファイルサイズは :max KB以下にしてください。',
'numeric' => ':attribute は :max 以下の数値を入力してください。',
'string' => ':attribute は :max 文字以下で入力してください。',
],
'max_digits' => ':attribute は :max 桁以下の数字で入力してください。',
'mimes' => ':attribute には :values タイプのファイルを指定してください。',
'mimetypes' => ':attribute には :values タイプのファイルを指定してください。',
'min' => [
'array' => ':attribute の項目数は :min 個以上にしてください。',
'file' => ':attribute のファイルサイズは :min KB以上にしてください。',
'numeric' => ':attribute は :min 以上の数値を入力してください。',
'string' => ':attribute は :min 文字以上で入力してください。',
],
'min_digits' => ':attribute は :min 桁以上の数字で入力してください。',
'missing' => ':attribute は入力しないでください。',
'missing_if' => ':other が :value の場合、:attribute は入力しないでください。',
'missing_unless' => ':other が :value でない限り、:attribute は入力しないでください。',
'missing_with' => ':values が指定されている場合、:attribute は入力しないでください。',
'missing_with_all' => ':values がすべて指定されている場合、:attribute は入力しないでください。',
'multiple_of' => ':attribute は :value の倍数である必要があります。',
'not_in' => '選択された :attribute は無効です。',
'not_regex' => ':attribute の形式が正しくありません。',
'numeric' => ':attribute には数値を入力してください。',
'password' => [
'letters' => ':attribute には少なくとも1文字以上の文字を含める必要があります。',
'mixed' => ':attribute には大文字と小文字をそれぞれ1文字以上含める必要があります。',
'numbers' => ':attribute には少なくとも1つの数字を含める必要があります。',
'symbols' => ':attribute には少なくとも1つの記号を含める必要があります。',
'uncompromised' => '指定された :attribute は過去のデータ漏洩に含まれています。別のパスワードを選択してください。',
],
'present' => ':attribute が存在している必要があります。',
'present_if' => ':other が :value の場合、:attribute が存在している必要があります。',
'present_unless' => ':other が :value でない限り、:attribute が存在している必要があります。',
'present_with' => ':values が指定されている場合、:attribute が存在している必要があります。',
'present_with_all' => ':values がすべて指定されている場合、:attribute が存在している必要があります。',
'prohibited' => ':attribute の入力は禁止されています。',
'prohibited_if' => ':other が :value の場合、:attribute の入力は禁止されています。',
'prohibited_unless' => ':other が :values のいずれでもない場合、:attribute の入力は禁止されています。',
'prohibits' => ':attribute は :other の入力を禁止しています。',
'regex' => ':attribute の形式が正しくありません。',
'required' => ':attribute は必須項目です。',
'required_array_keys' => ':attribute には [:values] のキーを含める必要があります。',
'required_if' => ':other が :value の場合、:attribute は必須項目です。',
'required_if_accepted' => ':other が承認された場合、:attribute は必須項目です。',
'required_if_declined' => ':other が拒否された場合、:attribute は必須項目です。',
'required_unless' => ':other が :values でない限り、:attribute は必須項目です。',
'required_with' => ':values が入力されている場合、:attribute は必須項目です。',
'required_with_all' => ':values がすべて入力されている場合、:attribute は必須項目です。',
'required_without' => ':values が入力されていない場合、:attribute は必須項目です。',
'required_without_all' => ':values がすべて入力されていない場合、:attribute は必須項目です。',
'same' => ':attribute と :other が一致していません。',
'size' => [
'array' => ':attribute の項目数は :size 個にしてください。',
'file' => ':attribute のファイルサイズは :size KBにしてください。',
'numeric' => ':attribute は :size を指定してください。',
'string' => ':attribute は :size 文字で入力してください。',
],
'starts_with' => ':attribute は [:values] のいずれかで始まる必要があります。',
'string' => ':attribute には文字列を入力してください。',
'timezone' => ':attribute には有効なタイムゾーンを指定してください。',
'unique' => '指定された :attribute は既に使用されています。',
'uploaded' => ':attribute のアップロードに失敗しました。',
'uppercase' => ':attribute は大文字で入力してください。',
'url' => ':attribute には有効なURLを入力してください。',
'ulid' => ':attribute には有効なULIDを指定してください。',
'uuid' => ':attribute には有効なUUIDを指定してください。',
/*
|--------------------------------------------------------------------------
| カスタムバリデーション言語行
|--------------------------------------------------------------------------
|
| ここでは、"attribute.rule" という命名規則を使用して、属性に対する
| カスタム検証メッセージを指定できます。
|
*/
'custom' => [
'email' => [
'required' => '連絡先としてメールアドレスの入力は必須です。',
],
],
/*
|--------------------------------------------------------------------------
| カスタムバリデーション属性名
|--------------------------------------------------------------------------
|
| 以下の言語行は、プレースホルダー ":attribute" を "email" のような
| 英語のキー名から "メールアドレス" のような読みやすい日本語名に置換します。
|
*/
'attributes' => [
'name' => 'お名前',
'username' => 'ユーザー名',
'email' => 'メールアドレス',
'password' => 'パスワード',
'password_confirmation' => 'パスワード(確認用)',
'tel' => '電話番号',
'phone' => '電話番号',
'postal_code' => '郵便番号',
'zip' => '郵便番号',
'address' => '住所',
'prefecture' => '都道府県',
'city' => '市区町村',
'title' => 'タイトル',
'body' => '本文',
'content' => '内容',
'description' => '説明',
'birthday' => '生年月日',
'gender' => '性別',
'age' => '年齢',
'price' => '価格',
'amount' => '数量',
'file' => 'ファイル',
'image' => '画像',
'avatar' => 'アバター画像',
'terms' => '利用規約',
'role' => '権限',
'category_id' => 'カテゴリー',
'tag_ids' => 'タグ',
],
];
4. 【ステップ3】フォーム属性名(attributes)の日本語化設定
ステップ2の言語ファイルを配置するだけでもメッセージは日本語になりますが、そのままでは以下のようにフィールド名(属性名)が英語のままになってしまいます。
email は必須項目です。(emailが英語のまま)⭕ attributes設定後:
メールアドレス は必須項目です。(自然な日本語に変換!)
属性名を日本語化するには、lang/ja/validation.php の 'attributes' => [...] 配列にフィールド名と日本語表記の対応関係を定義します。
実務でよく使われる attributes マッピング早見表
| フィールド名(キー) | 日本語表示名(attributes) | 主な利用シーン |
|---|---|---|
name, username |
お名前、ユーザー名 | 会員登録、プロフィール |
email |
メールアドレス | ログイン、お問い合わせ |
password, password_confirmation |
パスワード、パスワード(確認用) | 認証、パスワードリセット |
tel, phone |
電話番号 | 注文フォーム、会員情報 |
postal_code, zip |
郵便番号 | 配送先入力、住所登録 |
address, prefecture, city |
住所、都道府県、市区町村 | 配送先入力、所在地 |
title, body, content |
タイトル、本文、内容 | ブログ投稿、問い合わせ内容 |
birthday, age, gender |
生年月日、年齢、性別 | アンケート、ユーザー属性 |
image, avatar, file |
画像、アバター画像、添付ファイル | ファイルアップロード |
terms, agree |
利用規約、同意 | チェックボックス同意確認 |
ネストされた配列・動的パラメータの日本語化
ECサイトの注文明細や複数行の入力フォームなど、配列形式の入力値(例:items.*.quantity や users.*.email)も attributes で日本語化可能です。
'attributes' => [
'items.*.name' => '商品名',
'items.*.quantity' => '数量',
'items.*.price' => '単価',
'users.*.email' => '参加者のメールアドレス',
],
5. 【応用】フォームやコントローラー単位で個別カスタマイズする方法
全体共通の日本語設定に加えて、「このフォームのこの項目だけ特別なエラーメッセージを出したい」というケースに対応する2つの実装パターンを解説します。
パターン1:FormRequest クラスでのカスタマイズ(推奨)
実務開発では FormRequest クラスを利用してバリデーションを分離するのがベストプラクティスです。FormRequest 内で messages() メソッドおよび attributes() メソッドを定義することで、そのフォーム専用の文言を設定できます。
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ContactFormRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:50'],
'email' => ['required', 'email', 'max:255'],
'message' => ['required', 'string', 'min:10', 'max:1000'],
'terms' => ['accepted'],
];
}
/**
* 項目名(属性名)の個別定義
*/
public function attributes(): array
{
return [
'name' => 'お名前(フルネーム)',
'message' => 'お問い合わせ内容',
'terms' => 'プライバシーポリシーへの同意',
];
}
/**
* エラーメッセージの個別カスタマイズ
*/
public function messages(): array
{
return [
'message.min' => ':attribute は状況を詳しく確認するため、:min 文字以上でご記入をお願いいたします。',
'terms.accepted' => 'お問い合わせを送信するには、:attribute が必須となります。',
];
}
}
パターン2:Controller内でのインラインバリデーション
小さな処理などでコントローラー内に直接 $request->validate() を書く場合でも、第2引数にカスタムメッセージ、第3引数にカスタム属性名を渡すことができます。
public function store(Request $request)
{
$validated = $request->validate(
// 1. バリデーションルール
[
'title' => 'required|max:100',
'body' => 'required',
],
// 2. カスタムメッセージ(省略時はデフォルトの日本語が適用)
[
'title.required' => '記事のタイトルを入力してください。',
],
// 3. カスタム属性名
[
'title' => '記事タイトル',
'body' => '記事本文',
]
);
// 保存処理...
}
6. 【Blade表示】ビューで日本語エラーメッセージを美しく表示する
設定した日本語エラーメッセージをBladeテンプレートで表示する方法です。
① 各入力項目の直下に個別エラーを表示する(@error)
ユーザーがどの項目でミスしたかを直感的に伝えるため、各フォームコントロールの直下に @error ディレクティブを使って配置します。
<!-- メールアドレス入力欄の例 -->
<div class="form-group mb-4">
<label for="email" class="block font-medium text-gray-700">メールアドレス <span class="text-red-500">*</span></label>
<input type="email"
name="email"
id="email"
value="{{ old('email') }}"
class="w-full mt-1 border rounded px-3 py-2 @error('email') border-red-500 bg-red-50 @enderror">
@error('email')
<p class="mt-1 text-sm text-red-600 font-medium">{{ $message }}</p>
@enderror
</div>
② フォーム上部にエラーサマリー(一括リスト)を表示する
ページ上部にエラー一覧をまとめて表示したい場合は $errors->any() と $errors->all() を使用します。
@if ($errors->any())
<div style="background-color: #fef2f2; border: 1px solid #fecaca; border-radius: 6px; padding: 16px; margin-bottom: 24px;">
<p style="color: #991b1b; font-weight: bold; margin-bottom: 8px;">⚠️ 入力内容にエラーがあります。ご確認の上、再度送信してください。</p>
<ul style="margin: 0; padding-left: 20px; color: #b91c1c; font-size: 0.9em;">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
7. 日本語化が反映されないときの原因とトラブルシューティング
設定したはずなのに「英語のまま表示される」「変更が反映されない」場合の代表的な原因と解決策です。
① 設定・設定キャッシュがクリアされていない
.env や config/app.php を書き換えた後、Laravelの設定キャッシュが残っていると変更が反映されません。以下のコマンドを実行してキャッシュをクリアしてください。
php artisan config:clear
php artisan cache:clear
② 言語ファイルの配置パスが間違っている
Laravelのバージョンによる配置場所のズレに注意してください。
- Laravel 10 / 11 / 12:
lang/ja/validation.php(ルート直下) - Laravel 9 以前:
resources/lang/ja/validation.php
③ ファイル名や配列キーのスペルミス
ファイル名が validations.php(複数形)になっていないか、lang/ja のフォルダ名が jp や japanese になっていないか確認してください(標準ロケール名は ja です)。
④ PHPのシンタックスエラー(カンマ抜けなど)
validation.php の配列定義内でカンマが抜けていたり構文エラーがあると、ファイル全体が読み込まれずフォールバック(英語)で処理されます。
8. まとめ&設定完了チェックリスト
Laravelのバリデーション日本語化は、手順さえ押さえれば数分で完了する必須の初期設定です。
- [ ]
.envにAPP_LOCALE=ja/APP_TIMEZONE=Asia/Tokyoが設定されているか? - [ ]
lang/ja/validation.php(またはresources/lang/ja/validation.php)が配置されているか? - [ ] 主要なバリデーションルール(
required,email,max等)に日本語が定義されているか? - [ ] フォームで使用する項目名(
name,email,password等)がattributes配列に定義されているか? - [ ]
php artisan config:clearを実行してキャッシュを更新したか?
適切な日本語バリデーションメッセージを用意して、ユーザーにとって分かりやすく使い勝手の良いWebアプリケーションを構築しましょう!

コメント