Write a custom Laravel validation rule

A custom rule is a class with validate(). The Vue page still prints form.errors for that field.

For your AI agent

Copies a prompt. Paste it into the AI agent you already have open.

Read https://laravel-vuejs.space/laravel-custom-validation-rule-vue.md
A custom rule is a class with validate(). The Vue page still prints form.errors for that field.
Do not reach into the database from this class for a unique check.
Show the diff. Do not commit.
On this page · 3 sections
  1. The fix
  2. What to avoid
  3. FAQ

People searching “Laravel custom validation rule” want one check that required and max cannot express. The Vue page does not learn a new error shape. It still reads form.errors.slug from the CRUD guide.

TL;DR

  • A custom rule is a class with validate().
  • The Vue page still prints form.errors for that field.
  • Do not throw.
  • Do not reach into the database from this class for a unique check.

Who it's for: Laravel + Vue developers

Applies to: Laravel 13 · Vue 3

The fix#

shell
php artisan make:rule SlugRule
php
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;

class SlugRule implements ValidationRule
{
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        if (! is_string($value) || preg_match('/^[a-z0-9]+(?:-[a-z0-9]+)*$/', $value) !== 1) {
            $fail('The slug may contain lowercase letters, numbers, and hyphens.');
        }
    }
}
php
$validated = $request->validate([
    'slug' => ['required', 'string', 'max:80', new SlugRule],
]);

Call $fail() with a sentence. Do not throw. Throwing skips the error bag and the Vue page gets a 500 instead of form.errors.slug.

What to avoid#

Gotcha

Do not reach into the database from this class for a unique check. Rule::unique() already does that, and a query inside validate() is easy to forget when the field is optional.

FAQ#

How do I write a custom Laravel validation rule?

A custom rule is a class with validate(). The Vue page still prints form.errors for that field.

What goes wrong with Laravel custom validation rule?

Many developers want one check that required and max cannot express. Do not throw.

Found this useful?

Ask questions, share what you built.

Join thousands of Laravel and Vue developers in our Facebook group, or get new posts in your Telegram feed. Sharing this article helps too.

Keep reading

Newsletter

Get the best of Laravel & Vue, once a month.

One short email with new guides, release notes worth reading and hand-picked community links. No spam, unsubscribe any time.