Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Client Validation Laravel Package

mrpunyapal/laravel-client-validation

Bring Laravel-style validation to the client with 100+ rules plus AJAX-backed unique/exists checks. TypeScript-ready, works with any backend, and integrates with Livewire, Filament, Alpine, or vanilla/React/Vue for real-time form feedback and FormRequest rule reuse.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Install the package** via Composer:
   ```bash
   composer require mrpunyapal/laravel-client-validation
   php artisan client-validation:install

This publishes the config file and sets up the package.

  1. Basic Alpine.js usage (most common workflow):

    <input x-validate="'required|email'" name="email">
    

    This applies Laravel-style validation rules (required|email) to the input field on blur (default behavior).

  2. First use case: Validate a form field in real-time with minimal setup:

    <div x-data="{ validation: validation({
        rules: { email: 'required|email' }
    }) }">
        <input x-model="validation.form.email" @blur="validation.validate('email')">
        <span x-text="validation.error('email')" x-show="validation.hasError('email')"></span>
    </div>
    

Key Starting Points

  • Alpine.js: Use x-validate directive (e.g., x-validate="'required|email'").
  • Livewire: Use x-wire-validate directive or the PHP trait.
  • Filament: Register the plugin and use HasClientValidation trait.
  • Vanilla JS: Use data-validate attributes or programmatic validation.

Implementation Patterns

1. Alpine.js Integration

Workflow: Real-Time Form Validation

<div x-data="validation({
    rules: {
        email: 'required|email|unique:users,email',
        password: 'required|min:8|confirmed:password_confirmation'
    },
    messages: {
        'email.required': 'Please enter your email',
        'password.min': 'Password must be at least 8 characters'
    }
})">
    <form @submit.prevent="submit(async (data) => {
        // Submit valid data to server
    })">
        <input x-model="form.email" @blur="validate('email')">
        <span x-text="error('email')" x-show="hasError('email')"></span>

        <input type="password" x-model="form.password" @blur="validate('password')">
        <span x-text="error('password')" x-show="hasError('password')"></span>

        <input type="password" x-model="form.password_confirmation">
    </form>
</div>

Pattern: Use validation() component for full form control. Validate fields on blur by default, but switch to live or submit modes as needed.

Dynamic Rules

<input x-validate="'required|min:{{ minLength }}'" name="username">

Pattern: Use Alpine.js reactivity to dynamically update validation rules.


2. Livewire Integration

Workflow: Sync Livewire and Client Validation

// In Livewire component
use MrPunyapal\ClientValidation\Livewire\WithClientValidation;

class CreateUser extends Component
{
    use WithClientValidation;

    public string $email = '';
    public string $password = '';

    protected $rules = [
        'email' => 'required|email',
        'password' => 'required|min:8',
    ];

    public function render()
    {
        return view('livewire.create-user');
    }
}
<!-- In Blade view -->
<div x-data="{ clientRules: @json($this->getClientRules()) }">
    <input wire:model="email"
           x-wire-validate="clientRules.email"
           name="email">
</div>

Pattern: Use WithClientValidation trait to auto-generate client-side rules from $rules. Sync Livewire model updates with client validation.

Livewire Events

protected $listeners = [
    'client-validation-error' => 'handleClientError',
];

public function handleClientError($data)
{
    // Handle client-side errors (e.g., update UI)
}

Pattern: Listen to client validation events to update Livewire state or UI without full page reloads.


3. Filament Integration

Workflow: Field-Level Validation

use MrPunyapal\ClientValidation\Filament\ClientValidatedField;

ClientValidatedField::make('email')
    ->clientValidation('required|email')
    ->clientValidationMode('live');

Pattern: Use ClientValidatedField for Filament forms. Configure validation mode (blur, live, or submit) per field.

Plugin Configuration

ClientValidationPlugin::make()
    ->enableRemoteValidation()
    ->validationMode('live');

Pattern: Register the plugin in AdminPanelProvider to enable global client validation.


4. Remote Validation (AJAX)

Workflow: Unique/Exists Rules

<input x-validate.live="'required|email|unique:users,email'"
       name="email">

Pattern: Use remote rules (unique, exists) with .live or .submit modifiers for real-time or on-submit validation.

Custom Remote Validator

const remote = new RemoteValidator({
    endpoint: '/api/validate',
    requestFormatter: (field, value, rule, params) => ({
        field_name: field,
        field_value: value,
        validation_rule: rule,
        rule_params: params
    })
});

Pattern: Configure RemoteValidator for non-Laravel backends (e.g., Express, Django). Use requestFormatter to match your API expectations.


5. FormRequest Integration

Workflow: Reuse Server-Side Rules

// Controller
public function create()
{
    $validation = ClientValidation::fromRequest(CreateUserRequest::class);
    return view('users.create', compact('validation'));
}
<div x-data="validation(@js($validation))">
    <!-- Form fields -->
</div>

Pattern: Extract client-side rules from FormRequest classes using ClientValidation::fromRequest(). Pass the rules to Alpine.js for seamless reuse.


6. Vanilla JS Integration

Workflow: Data Attributes

<form data-validate>
    <input name="email"
           data-rules="required|email"
           data-validate-on="blur">
</form>

Pattern: Use data-validate and data-rules attributes for lightweight validation without frameworks.

Programmatic Validation

import { LaravelValidator } from 'laravel-client-validation/core';

const validator = new LaravelValidator({
    rules: { email: 'required|email' }
});

const result = await validator.validateField('email', 'test@example.com');

Pattern: Use LaravelValidator for custom validation logic (e.g., in React/Vue components or utility functions).


Gotchas and Tips

Pitfalls

  1. Remote Rule Timing:

    • Remote rules (unique, exists) trigger AJAX requests. Ensure your backend endpoint is configured correctly (e.g., CSRF protection, rate limiting).
    • Fix: Use debounce_ms in config to avoid excessive requests:
      'debounce_ms' => 500, // 500ms delay for live validation
      
  2. Livewire Version Conflicts:

    • The package auto-detects Livewire v3/v4, but custom directives (e.g., x-wire-validate) may behave differently.
    • Fix: Test in both versions or explicitly set the version in config:
      'livewire_version' => 'v4',
      
  3. Alpine.js Scope Issues:

    • Nested x-data blocks may not inherit validation state.
    • Fix: Lift validation logic to a parent component or use x-model with explicit field names.
  4. CSRF Token for Remote Validation:

    • Remote rules require CSRF tokens for Laravel endpoints. If using custom backends, configure RemoteValidator to include tokens:
      const remote = new RemoteValidator({
          csrfHeaderName: 'X-CSRF-TOKEN',
          csrfTokenResolver: () => document.querySelector('meta[name="csrf-token"]')?.content
      });
      
  5. Rule Parameter Escaping:

    • Dynamic rule parameters (e.g., min:{{ minLength }}) must be sanitized to avoid XSS.
    • Fix: Use Alpine.js text binding or sanitize parameters server-side:
      <input x-validate="'required|min:' + minLength" name="username">
      
  6. Filament Field Initialization:

    • Custom fields using HasClientValidation must call initializeClientValidation() in their constructor.
    • Fix: Extend ClientValidatedField or manually initialize:
      public function __construct()
      {
          parent::__construct();
          $this->initializeClientValidation();
      }
      

Debugging Tips

  1. Validation Logs:

    • Enable debug mode in config to log validation events:
      'debug' => true,
      
    • Check browser console for client-validation:debug logs.
  2. Rule Testing:

    • Test individual rules in isolation using the LaravelValidator:
      const validator = new LaravelValidator();
      console.log(validator.testRule('email', 'test@example.com', 'required'));
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
monarobase/country-list
nasirkhan/laravel-sharekit
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity