> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Precognition

> A Laravel feature that runs server-side validation in real time before a form is submitted.

## What is Precognition

Precognition is a mechanism that runs server-side validation before a form is submitted.
You can use your Laravel rules as-is on the frontend without redefining them.

Unlike normal requests, Precognition requests execute a route's middleware and form request validation, but not the controller method body itself.
That makes it well-suited to real-time validation as the user types.

## Installation

In Laravel 13, you don't need to install the backend `laravel/precognition` package.
What you do need is a frontend helper package.

* Vue: `laravel-precognition-vue`
* React: `laravel-precognition-react`
* Alpine.js: `laravel-precognition-alpine`

```shell theme={null}
npm install laravel-precognition-vue
```

```shell theme={null}
npm install laravel-precognition-react
```

```shell theme={null}
npm install laravel-precognition-alpine
```

<Info>
  Inertia has built-in Precognition support from 2.3, and it also works out of the box in Inertia 3.
  When using Inertia forms, you typically don't need to add `laravel-precognition-vue` / `laravel-precognition-react`.
</Info>

## Backend configuration

Add the `HandlePrecognitiveRequests` middleware to your route.
It's practical to gather validation rules into a form request.
Consolidating rules into a form request makes reuse and separation of concerns easier.

```php theme={null}
use App\Http\Requests\StoreUserRequest;
use Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests;
use Illuminate\Support\Facades\Route;

Route::post('/users', function (StoreUserRequest $request) {
    // Only executed on a real submission
})->middleware([HandlePrecognitiveRequests::class]);
```

If you have custom middleware with side effects, skip them during Precognition.

```php theme={null}
public function handle(Request $request, Closure $next): mixed
{
    if (! $request->isPrecognitive()) {
        Interaction::incrementFor($request->user());
    }

    return $next($request);
}
```

## Frontend integration

### Alpine.js (Blade)

```html theme={null}
<form x-data="{
    form: $form('post', '/users', { name: '', email: '' }),
}">
    @csrf
    <input x-model="form.name" @change="form.validate('name')" />
    <template x-if="form.invalid('name')">
        <div x-text="form.errors.name"></div>
    </template>
</form>
```

### Vue (Inertia.js)

```vue theme={null}
<script setup>
import { useForm } from 'laravel-precognition-vue';

const form = useForm('post', '/users', {
    name: '',
    email: '',
});
</script>

<template>
    <input v-model="form.name" @change="form.validate('name')" />
    <div v-if="form.invalid('name')">{{ form.errors.name }}</div>
</template>
```

### React (Inertia.js)

```jsx theme={null}
import { useForm } from 'laravel-precognition-react';

const form = useForm('post', '/users', {
    name: '',
    email: '',
});

<input
    value={form.data.name}
    onChange={(e) => form.setData('name', e.target.value)}
    onBlur={() => form.validate('name')}
/>
```

### Vanilla JS with Axios

The Precognition library uses Axios.
To use your existing Axios instance, swap it in with `client.use()`.

```js theme={null}
import Axios from 'axios';
import { client } from 'laravel-precognition-vue';

window.axios = Axios.create();
window.axios.defaults.headers.common['Authorization'] = authToken;

client.use(window.axios);
```

## Controlling validation timing

Use `validate()` to validate individual inputs.

```js theme={null}
form.validate('email');
```

You can adjust the debounce time with `setValidationTimeout()`.

```js theme={null}
form.setValidationTimeout(3000);
```

If you want to validate files every time, use `validateFiles()`.

```js theme={null}
form.validateFiles();
```

You can validate array inputs using wildcards.

```js theme={null}
form.validate('users.*.email');
```

## Form helper

`useForm()` handles submission and error state together.

* `validating`: A validation request is in progress
* `processing`: A submission is in progress
* `errors`: A list of errors
* `valid('field')` / `invalid('field')`: The field's validation state
* `submit()`: Perform a regular submission

```js theme={null}
const submit = () => form.submit()
    .then(() => form.reset());
```

## Comparing regular requests and Precognition requests

The diagram below shows the difference between how regular and Precognition requests are handled.

```mermaid theme={null}
sequenceDiagram
    participant User as User
    participant Frontend as Frontend
    participant Server as Laravel server

    User->>Frontend: Fill in the form
    Frontend->>Server: Precognition request (Precognition: true header)
    Server->>Server: Run validation (controller logic not executed)
    Server-->>Frontend: Validation result
    Frontend-->>User: Display real-time errors
    User->>Frontend: Submit form
    Frontend->>Server: Regular request
    Server-->>Frontend: Response
```

## Related links

* [Laravel official: Precognition](https://laravel.com/docs/precognition)
* [Laravel official: Validation](https://laravel.com/docs/validation)
