This post is more than a year old. There is a chance the content is outdated.

Available Livewire 3 PHP Attributes

Available Livewire 3 PHP Attributes


Livewire 3 introduces a hand full of PHP attributes you can use in your components. So far there is no API reference in the new documentation, so here's a list of them from the source:

Computed

To create a computed property, you can add the #[Computed] attribute above any method in your Livewire component. Once the attribute has been added to the method, you can access it like any other property.

1#[Computed]
2public function user()
3{
4 return User::find($this->userId);
5}

Because the #[Computed] attribute has been added to the user() method, the value is accessible in other methods in the component and within the Blade template.

JS

Sometimes there are actions in your component that don't need to communicate with the server and can be more efficiently written using only JavaScript.

In these cases, rather than writing the actions inside your Blade template or another file, your component action may return the JavaScript function as a string. If the action is marked with the #[Js] attribute, it will be callable from your application's frontend:

1#[Js]
2public function reset()
3{
4 return <<<'JS'
5 $wire.query = '';
6 JS;
7}

Just like #[Js] methods, you can access the current component's $wire object inside the expression.

Layout

To use a different layout for a specific component, you can place Livewire's #[Layout] attribute above the component's render() method, passing it the relative view path of your custom layout:

1#[Layout('layouts.app')]
2public function render()
3{
4 return view('livewire.create-post');
5}

Or if you prefer, you can use this attribute above the class declaration.

Locked

Livewire properties are able to be modified freely on both the frontend and backend using utilities like wire:model. If you want to prevent a property — like a model ID — from being modified on the frontend, you can use Livewire's #[Locked] attribute:

1#[Locked]
2public $id;

Modelable

Livewire provides a #[Modelable] attribute you can add to any child component property to make it modelable from a parent component.

Below is the TodoInput component with the #[Modelable] attribute added above the $value property to signal to Livewire that if wire:model is declared on the component by a parent it should bind to this property:

1<?php
2 
3namespace App\Livewire;
4 
5use Livewire\Component;
6 
7class TodoInput extends Component
8{
9 #[Modelable]
10 public $value = '';
11 
12 public function render()
13 {
14 return view('livewire.todo-input');
15 }
16}

On

To listen for an event in a Livewire component, add the #[On] attribute above the method you want to be called when a given event is dispatched:

1#[On('post-created')]
2public function updatePostList($title)
3{
4 // ...
5}

Reactive

By default, Livewire props are not reactive. When using Livewire, every component is an island. This means that when an update is triggered on the parent and a network request is dispatched, only the parent component's state is sent to the server to re-render - not the child component's.

But, if you want or need a prop to be reactive, you can easily enable this behavior using the #[Reactive] attribute parameter:

1#[Reactive]
2public $todos;

Renderless

Sometimes there might be an action in your component with no side effects that would change the rendered Blade template when the action is invoked. If so, you can skip the render portion of Livewire's lifecycle by adding the #[Renderless] attribute above the action method:

1#[Renderless]
2public function incrementViewCount()
3{
4 $this->post->incrementViewCount();
5}

Rule

If you prefer to co-locate your component's validation rules with the properties directly, you can use Livewire's #[Rule] attribute:

1#[Rule('required|min:3')]
2public $title = '';
3 
4#[Rule('required|min:3')]
5public $content = '';

Title

If you have a full page component with the following HTML:

1<head>
2 <title>{{ $title ?? 'Page Title' }}</title>
3</head>

Then you can set that title from the component:

1#[Title('Create Post')]
2public function render()
3{
4 return view('livewire.create-post');
5}

URL

Livewire allows you to store component properties in the URL's query string.

Property values are lost from page refreshes. To preserve the property value across page loads so that a visitor can refresh the page or share the URL, we can store the property value in the URL's query string by adding the #[Url] attribute above the property like so:

1#[Url]
2public $search = '';

Initializing properties from the URL

You can set a default value by passing it to the query string:

https://example.com/users?search=bob

1#[Url]
2public $search = ''; // Will be set to "bob"...

Using an alias

You can specify a query string alias by providing the as parameter to the #[Url] attribute:

1#[Url(as: 'q')]
2public $search = '';

Now, when a user types "bob" into the search field, the URL will show: https://example.com/users?q=bob instead of ?search=bob.

Display on page load

If you want the ?search entry to always be included in the query string, even when the value is empty, you can provide the keep parameter to the #[Url] attribute:

1#[Url(keep: true)]
2public $search = '';

Now, when the page loads, the URL will be changed to the following: https://example.com/users?search=

Storing in history

To force Livewire to use history.pushState when updating the URL, you can provide the history parameter to the #[Url] attribute:

1#[Url(history: true)]
2public $search = '';

In the example above, when a user changes the search value from "bob" to "frank" and then clicks the browser's back button, the search value (and the URL) will be set back to "bob" instead of navigating to the previously visited page.

I'm hoping soon the new documentation will have an API reference like V2 did, but until then I hope this helps.

Anthony Rappa

By Anthony Rappa

Hello! I'm a full stack developer from Long Island, New York. Working mainly with Laravel, Tailwind, Livewire, and Alpine.js (TALL Stack). I share everything I know about these tools and more, as well as any useful resources I find from the community. You can find me on GitHub and LinkedIn.