Forms and validation
User input cannot be trusted: a field may be empty, too long or hold something unexpected. In Laravel validation rules are described in one array, and the framework shows the errors itself.
The form
Every form with the POST method must contain the @csrf directive — it adds a hidden field with a protection token:
<form method="POST" action="/posts">
@csrf
<input type="text" name="title">
<textarea name="body"></textarea>
<button type="submit">Save</button>
</form>Validating data
The validate() method takes the rules and returns only the validated fields:
public function store(Request $request)
{
$data = $request->validate([
'title' => 'required|max:255',
'body' => 'required',
]);
Post::create($data);
return redirect('/posts');
}If the data fails validation, Laravel sends the user back to the form by itself — the code below validate() does not run.
Common rules
| Rule | What it checks |
|---|---|
required | The field is filled in |
email | A valid email address |
min:8 / max:255 | String length or number size |
integer | An integer |
unique:users,email | The value is not in the users table yet |
confirmed | Matches the ..._confirmation field |
Several rules are separated with a vertical bar or passed as an array.
Showing errors
The @error directive shows the message for a specific field:
<input type="text" name="title">
@error('title')
<p class="error">{{ $message }}</p>
@enderrorKeeping the input
So that fields are not cleared after an error, put the previous value back with the old() function:
<input type="text" name="title" value="{{ old('title') }}">A success message
After saving, redirect the user and pass a one-time message:
return redirect('/posts')->with('status', 'Post saved');@if (session('status'))
<p>{{ session('status') }}</p>
@endifThe message lives until the next request and disappears after a page refresh.
Common mistake
If the form has no @csrf, Laravel answers the submission with a 419 "Page Expired" error. The token protects against forged requests from other sites, so do not turn the check off — just add the directive to the form.