I stand up for children in need. Please join me in helping this family.

Skip to content
Steven Roland

Enhancing User Experience with Laravel Precognition

Laravel Precognition is a powerful feature that allows developers to provide real-time form validation without duplicating validation rules on the frontend. By anticipating the outcome of future HTTP requests, Precognition streamlines the validation process and significantly improves user experience. In this post, we'll explore how to implement Precognition and showcase some practical examples.

Getting Started with Precognition

To use Precognition, you first need to add the HandlePrecognitiveRequests middleware to your route:

use App\Http\Requests\CreateUserRequest;
use Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests;

Route::post('/users', function (CreateUserRequest $request) {
    // ...
})->middleware([HandlePrecognitiveRequests::class]);

Implementing Live Validation

Let's look at an example using Vue.js and Inertia. First, install the necessary package:

npm install laravel-precognition-vue

Now, create a form component:

<script setup>
import { useForm } from 'laravel-precognition-vue';
const form = useForm('post', '/users', {
    name: '',
    email: '',
    password: '',
});
const submit = () => form.submit();
</script>

<template>
    <form @submit.prevent="submit">
        <input v-model="form.name" @change="form.validate('name')" />
        <div v-if="form.invalid('name')">{{ form.errors.name }}</div>
        <input type="email" v-model="form.email" @change="form.validate('email')" />
        <div v-if="form.invalid('email')">{{ form.errors.email }}</div>
        <input type="password" v-model="form.password" @change="form.validate('password')" />
        <div v-if="form.invalid('password')">{{ form.errors.password }}</div>
        <button :disabled="form.processing">Create User</button>
    </form>
</template>

This setup provides real-time validation as the user types, using your server-side validation rules.

Suggested Usages

  • Multi-step Forms: Use Precognition to validate each step before allowing the user to proceed.

    <script setup>
    import { useForm } from 'laravel-precognition-vue';
    
    const form = useForm('post', '/registration', {
        step: 1,
        name: '',
        email: '',
        // ... other fields
    });
    
    const nextStep = async () => {
        await form.validate(['name', 'email']);
        if (!form.hasErrors()) {
            form.step++;
        }
    };
    </script>
  • Dynamic Form Fields: Validate fields that depend on other inputs.

    <script setup>
    import { useForm, watch } from 'laravel-precognition-vue';
    
    const form = useForm('post', '/order', {
        product_id: null,
        quantity: 1,
    });
    
    watch(() => form.product_id, () => {
        form.validate('quantity');
    });
    </script>
  • Debounced Validation: Implement debounced validation for fields like usernames or email addresses.

    <script setup>
    import { useForm } from 'laravel-precognition-vue';
    import { debounce } from 'lodash';
    
    const form = useForm('post', '/register', {
        username: '',
    });
    
    const debouncedValidate = debounce(() => form.validate('username'), 300);
    </script>
    
    <template>
        <input v-model="form.username" @input="debouncedValidate" />
    </template>
  • File Upload Validation: Use Precognition to validate file uploads before sending the entire form.

    <script setup>
    import { useForm } from 'laravel-precognition-vue';
    
    const form = useForm('post', '/profile', {
        avatar: null,
    });
    
    const validateFile = (event) => {
        form.avatar = event.target.files[0];
        form.validate('avatar');
    };
    </script>
    
    <template>
        <input type="file" @change="validateFile" />
        <div v-if="form.invalid('avatar')">{{ form.errors.avatar }}</div>
    </template>

Best Practices

  • Keep Backend Validation: Always maintain server-side validation as the ultimate authority.

  • Handle Network Errors: Provide feedback for network issues during validation.

  • Progressive Enhancement: Ensure your forms work without JavaScript as a fallback.

  • Performance Considerations: Be mindful of the number of requests made, especially for high-traffic applications.

Laravel Precognition offers a powerful way to enhance user experience by providing immediate feedback without sacrificing the security and reliability of server-side validation. By implementing Precognition in your Laravel applications, you can create more responsive and user-friendly forms while maintaining a single source of truth for your validation rules.

Support My Work

If you enjoy my content, consider supporting me through Buy Me a Coffee or GitHub Sponsors.

Buy Me A Coffee
or

More posts

Customizing Taxonomy Routes in Statamic

Learn how to customize taxonomy routes in Statamic for better site navigation and SEO. Use default routes or opt for custom solutions with Laravel or the Bonus Routes addon to create user-friendly and integrated URLs.

Enhancing User Experience with Laravel Precognition

Laravel Precognition enables real-time form validation using server-side rules. It integrates with frontend frameworks like Vue.js to provide immediate feedback. Key uses include multi-step forms, dynamic field validation, debounced validation, and file upload checks. Best practices involve maintaining backend validation, handling network errors, and considering performance implications.

Laravel Cashier (Paddle): Simplifying Subscription Billing

Laravel Cashier Paddle simplifies Paddle subscription billing in Laravel apps. It handles subscriptions, status checks, webhooks, and one-time charges. Ideal for SaaS, digital content subscriptions, and e-learning platforms.