docs/attribute-json.md
The #[Json] attribute marks an action as a JSON endpoint, returning data directly to JavaScript. Validation errors trigger a promise rejection with structured error data. This is ideal for actions consumed by JavaScript rather than rendered in Blade.
Apply the #[Json] attribute to any action method that returns data for JavaScript consumption:
<?php // resources/views/components/⚡search.blade.php
use Livewire\Attributes\Json;
use Livewire\Component;
use App\Models\Post;
new class extends Component {
#[Json] // [tl! highlight]
public function search($query)
{
return Post::where('title', 'like', "%{$query}%")
->limit(10)
->get();
}
};
<div x-data="{ query: '', posts: [] }">
<input
type="text"
x-model="query"
x-on:input.debounce="$wire.search(query).then(data => posts = data)"
>
<ul>
<template x-for="post in posts">
<li x-text="post.title"></li>
</template>
</ul>
</div>
The search() method returns posts directly to Alpine, where they're stored in the posts array and rendered client-side.
JSON methods resolve with the return value on success, and reject on validation failure:
On success:
let data = await $wire.search('query')
// data = [ { id: 1, title: '...' }, ...]
On validation failure:
try {
let data = await $wire.save()
} catch (e) {
// e.status = 422
// e.errors = { name: ['The name field is required.'] }
}
Or using .catch():
$wire.save()
.then(data => {
// Handle success
console.log(data)
})
.catch(e => {
if (e.status === 422) {
// Handle validation errors
console.log(e.errors)
}
})
When a promise is rejected, the error object has this structure:
{
status: 422, // HTTP status code (422 for validation errors)
body: null, // Raw response body (null for validation errors)
json: null, // Parsed JSON (null for validation errors)
errors: {...} // Validation errors object
}
For HTTP errors (500, etc.), the shape is the same but with the actual response data:
{
status: 500,
body: '<html>...</html>',
json: null,
errors: null
}
The #[Json] attribute automatically applies two behaviors:
These behaviors match what you'd expect from an API-style endpoint.
Use #[Json] when:
[!warning] Validation errors are isolated Validation errors from JSON methods are only returned via promise rejection. They don't appear in
$wire.$errorsor the component's error bag. This is intentional—JSON methods are self-contained and don't affect the component's rendered state.