Download as pdf or txt
Download as pdf or txt
You are on page 1of 186

QUICKSTART

INSTALL LIVEWIRE
Include the PHP.

Include the JavaScript (on every page that will be using Livewire).

CREATE A COMPONENT
Run the following command to generate a new Livewire component called counter.

Running this command will generate the following two files:


Let's add some text to the view so we can see something tangible in the browser.

Livewire components MUST have a single root element.


INCLUDE THE COMPONENT
Think of Livewire components like Blade includes. You can insert <livewire:some-component />
anywhere in a Blade view and it will render.

VIEW IT IN THE BROWSER


Load the page you included Livewire on in the browser. You should see "Hello World!".

ADD "COUNTER" FUNCTIONALITY


Replace the generated content of the counter component class and view with the following:
VIEW IT IN THE BROWSER
Now reload the page in the browser, you should see the counter component rendered. If you click
the "+" button, the page should automatically update without a page reload. Magic .
REFERENCE

TEMPLATE DIRECTIVES
These are directives added to elements within Livewire component templates.

Directive Description
wire:key="foo" Acts as a reference point for Livewire's DOM diffing
system. Useful for adding/removing elements, and
keeping track of lists.
wire:click="foo" Listens for a "click" event, and fires the "foo" method
in the component.
wire:click.prefetch="foo" Listens for a "mouseenter" event, and "prefetches"
the result of the "foo" method in the component.
Then, if it is clicked, will swap in the "prefetched"
result (without an extra request), if it's not clicked,
will throw away the cached result.
wire:keydown.enter="foo" Listens for a keydown event on the enter key, which
fires the "foo" method in the component.
wire:foo="bar" Listens for a browser event called "foo". (You can
listen for any browser DOM event - not just those
fired by Livewire).
wire:model="foo" Assuming $foo is a public property on the
component class, every time an input element with
this directive is updated, the property synchronizes
with its value.
wire:model.debounce.100ms="foo" Debounces the input events emitted by the element
every 100 milliseconds.
wire:model.lazy="foo" Lazily syncs the input with its corresponding
component property at rest.
wire:model.defer="foo" Defers syncing the input with the Livewire property
until an "action" is performed. This saves drastically
on server roundtrips.
wire:poll.500ms="foo" Runs the "foo" method on the component class every
500 milliseconds.
wire:init="foo" Runs the "foo" method on the component
immediately after it renders on the page.
wire:loading Hides the element by default, and makes it visible
while network requests are in transit.
wire:loading.class="foo" Adds the foo class to the element while network
requests are in transit.
wire:loading.class.remove="foo" Removes the foo class while network requests are in
transit.
wire:loading.attr="disabled" Adds the disabled="true" attribute while network
requests are in transit.
wire:dirty Hides the element by default, and makes it visible
while the element's state is "dirty" (different from
what exists on the backend).
wire:dirty.class="foo" Adds the foo class to the element while it's dirty.
wire:dirty.class.remove="foo" Removes the foo class while the element is dirty.
wire:dirty.attr="disabled" Adds the disabled="true" attribute while the
element's dirty.
wire:target="foo" Scopes wire:loading and wire:dirty functionality
to a specific action.
wire:ignore Instructs Livewire to not update the element or its
children when updating the DOM from a server
request. Useful when using third-party JavaScript
libraries within Livewire components.
wire:ignore.self The "self" modifier restricts updates to the element
itself, but allows modifications to its children.

ALPINE COMPONENT OBJECT ($WIRE)


These are methods and properties available on the $wire object provided to Alpine components
within a Livewire template.

API Description
$wire.foo Get the value of the "foo" property on the
Livewire component
$wire.foo = 'bar' Set the value of the "foo" property on the
Livewire component
$wire.bar(..args) Call the "bar" method (with params) on the
Livewire component
let baz = await $wire.bar(..args) Call the "bar" method, but wait for the response
and set baz to it
$wire.on('foo', (..args) => {}) Call a function when the "foo" event is emitted
$wire.emit('foo', ...args) Emit the "foo" event to all Livewire components
$wire.emitUp('foo', ...args) Emit the "foo" event to parent components
$wire.emitSelf('foo', ...args) Emit the "foo" event only to this component
$wire.get('foo') Get the "foo" property
$wire.set('foo', 'bar') Set the "foo" property on the component
$wire.set('foo', 'bar', true) Defer setting the "foo" property on the
component
$wire.call('foo', ..args) Call the "foo" method with params on the
component
x-data="{ foo: Entagle the value of "foo" between Livewire and
$wire.entangle('foo') }"
Alpine
$wire.entangle('foo').defer Only update Livewire's "foo" next time a
Livewire request is fired

GLOBAL LIVEWIRE JAVASCRIPT OBJECT


These are methods available on the window.Livewire object in the frontend. These are for deeper
Livewire interaction and customization.
Method Description
Livewire.first() Get the first Livewire component's JS
object on the page
Livewire.find(componentId) Get a Livewire component by it's ID
Livewire.all() Get all the Livewire components on a page
Livewire.directive(directiveName, (el, Register a new Livewire directive
directive, component) => {})
(wire:custom-directive)
Livewire.hook(hookName, (...) => {}) Call a method when JS lifecycle hook is
fired. Read more
Livewire.onLoad(() => {}) Fires when Livewire is first finished
loading on a page
Livewire.onError((message, statusCode) => Fires when a Livewire request fails. You
{})
can return false from the callback to
prevent Livewire's default behavior
Livewire.onPageExpired((response, When the page or session has expired it
message) => {})
executes the callback instead of Livewire's
page expired dialog
Livewire.emit(eventName, ...params) Emit an event to all Livewire components
listening on a page
Livewire.emitTo(componentName, Emit an event to specific component name
eventName, ...params)
Livewire.on(eventName, (...params) => {}) Listen for an event to be emitted from a
component
Livewire.start() Boot Livewire on the page (done for you
automatically via @livewireScripts)
Livewire.stop() Tear down Livewire from the page
Livewire.restart() Stop, then start Livewire on the page
Livewire.rescan() Re-scan the DOM for newly added
Livewire components

JAVASCRIPT HOOKS
These are "hooks" you can listen for in JavaScript. These allow you to hook into very specific parts
of a Livewire component's JavaScript lifecycle for third-party packages or deep customizations.
The abilities unlocked here are immense. A significant portion of Livewire's core uses these hooks
to provide functionality.

Name Params Description


component.initialized (component) A new component has been initialized
element.initialized (el, component) A new element has been initialized
element.updating (fromEl, toEl, An element is about to be updated after a
component)
Livewire request
element.updated (el, component) An element has just been updated from a
Livewire request
element.removed (el, component) An element has been removed after a
Livewire request
message.sent (message, A new Livewire message was just sent to
component)
the server
message.failed (message, A Livewire ajax request (message) failed
component)
message.received (message, A message has been received (but hasn't
component)
affected the DOM)
message.processed (message, A message has been fully received and
component)
implemented (DOM updates, etc...)

COMPONENT CLASS LIFECYCLE HOOKS


These are methods you can declare in your Livewire component classes to run code at specific
times in the backend's lifecycle. Read Full Documentation

Name Description
boot() Called on all requests, immediately after the component is
instantiated, but before any other lifecycle methods are called
booted() Called on all requests, after the component is mounted or
hydrated, but before any update methods are called
mount(...$params) Called when a Livewire component is newed up (think of it
like a constructor)
hydrate() Called on subsequent Livewire requests after the component
has been hydrated, but before any other action occurs
hydrateFoo() Runs after a property called $foo is hydrated
dehydrate() Called after render(), but before the component has been
dehydrated and sent to the frontend
dehydrateFoo() Runs before a property called $foo is dehydrated
updating() Runs before any update to the Livewire component's data
(Using wire:model, not directly inside PHP)
updated($field, Called after a property has been updated
$newValue)
updatingFoo() Runs before a property called $foo is updated
updatedFoo($newValue) Called after the "foo" property has been updated
updatingFooBar() Runs before updating a nested property bar on the $foo
property
updatedFooBar($newValue) Called after the nested "bar" key on the "foo" property has
been updated
render() Called before "dehydrate" and renders the Blade view for the
component

COMPONENT CLASS PROTECTED PROPERTIES


Livewire provides core functionality through protected properties on a component's class. Most of
these have corresponding methods by the same name if you prefer to return values in a method,
rather than declare them as properties.
Name Description
$queryString Declare which properties to "bind" to the query sting. Read Docs
$rules Specify validation rules to be applied to properties when calling $this-
>validate(). Read Docs
$listeners Specify which events you want to listen for emitted by other components.
Read Docs
$paginationTheme Specify whether you want to use Tailwind or Bootstrap for you pagination
theme. Read Docs

COMPONENT CLASS TRAITS


These are traits that unlock additional functionality in a Livewire component. Usually for features
that are considered best as "opt-in".

Name Description
WithPagination This trait enables Livewire-based pagination instead of Laravel's stock
pagination system. Read Docs
WithFileUploads This trait enables adding wire:model to an input of type="file". Read
Docs
CLASS METHODS

Name Description
$this->emit($eventName, ...$params) Emit an event to other components on the
page
$this->emit($eventName, ...$params)- Emit an event to parent components on
>up()
the page
$this->emit($eventName, ...$params)- Emit an event only to THIS component
>self()
$this->emit($eventName, ...$params)- Emit an event to any component
>to($componentName)
matching the provided name
$this->dispatchBrowserEvent($eventName, Dispatch a browser event from this
...$params)
component's root element
$this->validate() Run the validation rules provided in the
$rules property against the public
component properties
$this->validate($rules, $messages) Run the provided validation rules against
the public properties
$this->validateOnly($propertyName) Run the $rules property validation
against a specific property provided and
not others
$this->validateOnly($propertyName, Run the provided validation rules against
$rules, $messages)
a specific property name
$this->redirect($url) Redirect to a new URL when the
Livewire request finishes and reaches the
frontend
$this->redirectRoute($routeName) Redirect to a specific route name
$this->skipRender() Skip running the ->render() method for
the current request. (Usually for
performance reasons)
$this->addError($name, $error) Add a specific error name and value to
the component's error bag manually
$this->resetValidation() Reset the currently stored validation
errors (clear them)
$this->fill([...$propertyData]) Set public property names to provided
values in bulk
$this->reset() Reset all public properties to their initial
(pre-mount) state
$this->reset($field) Reset a specific public property to its pre-
mount state
$this->reset([...$fields]) Reset multiple specific properties
$this->all() Return key->value pairs of property data
$this->only([...$propertyNames]) Return key->value pairs of property data
only for a specific set of property names
$this->except([...$propertyNames]) Return key->value pairs of property data
except for a specific set of property
names

PHP TESTING METHODS


These are methods available on Livewire's testing helpers. Read Full Documentation
Name
->assertSet($propertyName, $value)
->assertNotSet($propertyName, $value)
->assertCount($propertyName, $value)
->assertPayloadSet($propertyName, $value)
->assertPayloadNotSet($propertyName, $value)
->assertSee($string)
->assertDontSee($string)
->assertSeeHtml($string)
->assertDontSeeHtml($string)
->assertSeeHtmlInOrder([$firstString, $secondString])
->assertSeeInOrder([$firstString, $secondString])
->assertEmitted($eventName)
->assertNotEmitted($eventName)
->assertDispatchedBrowserEvent($eventName)
->assertHasErrors($propertyName)
->assertHasErrors($propertyName, ['required', 'min:6'])
->assertHasNoErrors($propertyName)
->assertHasNoErrors($propertyName, ['required', 'min:6'])
->assertRedirect()
->assertRedirect($url)
->assertViewHas($viewDataKey)
->assertViewHas($viewDataKey, $expectedValue)
->assertViewHas($viewDataKey, function ($dataValue) {})
->assertViewIs('livewire.some-view-name')
->assertFileDownloaded($filename)
There are also Laravel testing response helpers available to check the presence of a component on
a given page.
Name
$response->assertSeeLivewire('some-component')
$response->assertDontSeeLivewire('some-component')

ARTISAN COMMANDS
These are the artisan commands Livewire makes available to make frequent tasks like creating
a component easier.
Name Params Description
artisan make:livewire Create a new component
artisan livewire:make Create a new component
artisan livewire:copy Copy a component
artisan livewire:move Move a component
artisan livewire:delete Delete a component
artisan livewire:touch Alias for livewire:make
artisan livewire:cp Alias for livewire:copy
artisan livewire:mv Alias for livewire:move
artisan livewire:rm Alias for livewire:delete
artisan livewire:stubs Publish Livewire stubs (used in the above
commands) for local modification
artisan livewire:publish Publish Livewire's config file to your
project (config/livewire.php)
artisan livewire:publish - Publish Livewire's config file AND its
-assets
frontend assets to your project
artisan Configure your cloud disk driver's S3
livewire:configure-s3-
bucket to clear temporary uploads after 24
upload-cleanup
hours
PHP LIFECYCLE HOOKS
These are hooks provided by Livewire in PHP for listening to lifecycle occurences at a global level
(not at a component level). These are used internally to provide a significant portion of Livewire's
core functionality, and can be used in ServiceProviders to further extend Livewire yourself.

Name Params Description


component.hydrate ($component, Run on EVERY component
$request)
hydration
component.hydrate.initial ($component, Run only on the INITIAL
$request)
hydration (When the
component is first loaded)
component.hydrate.subsequent ($component, Run only AFTER the initial
$request)
component request
component.dehydrate ($component, Run on EVERY component
$response)
dehydration
component.dehydrate.initial ($component, Run only on the INITIAL
$response)
dehydration (When the
component is first loaded)
component.dehydrate.subsequent ($component, Run on dehydrate AFTER
$response)
the initial component request
property.hydrate ($name, $value, Run when a specific property
$component,
is hydrated
$request)
property.dehydrate ($name, $value, Run when a specific property
$component,
is dehydrated
$response)
UPGRADING FROM 1.X
THE ESSENTIALS

INSTALLATION

Requirements
1. PHP 7.2.5 or higher
2. Laravel 7.0 or higher

Visit the composer.json file on Github for the complete list of package requirements.

Install The Package

Include The Assets


Add the following Blade directives in the head tag, and before the end body tag in your template.

You can alternatively use the tag syntax.


That's it! That's all you need to start using Livewire. Everything else on this page is optional.

Publishing The Config File


Livewire aims for "zero-configuration" out-of-the-box, but some users require more configuration
options. You can publish Livewire's config file with the following artisan command:

Publishing Frontend Assets


If you prefer the JavaScript assets to be served by your web server not through Laravel, use the
livewire:publish command:

To keep the assets up-to-date and avoid issues in future updates, we highly recommend adding
the command to the post-autoload-dump scripts in your composer.json file:
Configuring The Asset Base URL
By default, Livewire serves its JavaScript portion (livewire.js) from the following route in your
app: /livewire/livewire.js.

The actual script tag that gets generated defaults to:


<script src="/livewire/livewire.js"></script>

There are two scenarios that will cause this default behavior to break:
1. You publish the Livewire assets and are now serving them from a sub-folder like "assets".
2. Your app is hosted on a non-root path on your domain. For example: https://your-
laravel-app.com/application. In this case, the actual assets will be served from
/application/livewire/livewire.js, but the generated script tag, will be trying to fetch
/livewire/livewire.js.

To solve either of these issues, you can configure the "asset_url" in config/livewire.php to
customize what's prepended to the src="" attribute.

For example, after publishing Livewire's config file, here are the settings that would fix the above
two issues:
1. 'asset_url' => '/assets'
2. 'asset_url' => '/application'
MAKING COMPONENTS

Introduction
Run the following artisan command to create a new Livewire component:

Livewire also supports "kebab" notation for new components.

Two new files were created in your project:


• app/Http/Livewire/ShowPosts.php

• resources/views/livewire/show-posts.blade.php

If you wish to create components within sub-folders, you can use the following different syntaxes:

Now, the two created files will be in sub-folders:


• app/Http/Livewire/Post/Show.php

• resources/views/livewire/post/show.blade.php

Generating Tests
Optionally, you can include the --test flag when creating a component, and a test file will be
created for you as well.
Inline Components
If you wish to create Inline components (Components without .blade.php files), you can add the
--inline flag to the command:

Now, only one file will be created:


• app/Http/Livewire/ShowPosts.php

Here's what it would look like:


RENDERING COMPONENTS

Inline Components
The most basic way to render a Livewire component on a page is using the <livewire: tag syntax:

Alternatively you can use the @livewire blade directive:

If you have a component inside of a sub-folder with its own namespace, you must use a dot (.)
prefixed with the namespace.

For example, if we have a ShowPosts component inside of a app/Http/Livewire/Nav folder, we


would indicate it as such:

Parameters

Passing Parameters
You can pass data into a component by passing additional parameters into the <livewire: tag.
For example, let's say we have a show-post component. Here's how you would pass in a $post
model.
Alternatively, this is how you can pass in parameters using the Blade directive.

Receiving Parameters
Livewire will automatically assign parameters to matching public properties.

For example, in the case of <livewire:show-post :post="$post"> , if the show-post


component has a public property named $post, it will be automatically assigned:

If for whatever reason, this automatic behavior doesn't work well for you, you can intercept
parameters using the mount() method:
In Livewire components, you use mount() instead of a class constructor
__construct() like you may be used to. NB: mount() is only ever called when the
component is first mounted and will not be called again even when the component is
refreshed or rerendered.

Like a controller, you can inject dependencies by adding type-hinted parameters before passed-in
ones.

Full-Page Components
If the main content of a page is a Livewire component, you can pass the component directly into a
Laravel route as if it were a controller.
By default, Livewire will render the ShowPosts component into the {{ $slot }} of a blade layout
component located at: resources/views/layouts/app.blade.php.

For more information on Laravel components, visit Laravel's documentation.

Configuring The Layout Component


If you want to specify a default layout other than the layouts.app, you can override the
livewire.layout config option.

If you need even more control, you can use the ->layout() method on the view instance you
return from render().
If your layout has an associated class file, you will need to reference that for any custom logic or
properties.

If you are using a non-default slot in the component, you can also chain on ->slot():

Alternatively, Livewire supports using traditional Blade layout files with @extends.

Given the following layout file:


You can configure Livewire to reference it using ->extends() instead of ->layout():

If you need to configure the @section for the component to use, you can configure that as well
with the ->section() method:

If you need to pass data from your components to your layout, you can pass the data along with
the layout method:

In some cases you don't need to pass your layout name or you want to pass layout data separately,
you can use layoutData method:
Route Parameters
Often you need to access route parameters inside your controller methods. Because we are no
longer using controllers, Livewire attempts to mimic this behavior through its mount method. For
example:

As you can see, the mount method in a Livewire component is acting like a controller method
would as far as its parameters go. If you visit /post/123, the $id variable passed into the mount
method will contain the value 123.
Route Model Binding
Like you would expect, Livewire components implement all functionality you're used to in your
controllers including route model binding. For example:

If you are using PHP 7.4, you can also typehint class properties, and Livewire will automatically
route-model bind to them. The following component's $post property will be automatically
injected with no need for the mount() method.

The Render Method


A Livewire component's render method gets called on the initial page load AND every subsequent
component update.

In simple components, you don't need to define a `render` method yourself. The base
Livewire component class has a dynamic `render` method included.
Returning Blade Views
The render() method is expected to return a Blade view, therefore, you can compare it to writing
a controller method. Here is an example:

Make sure your Blade view only has ONE root element.

Returning Template String


In addition to Blade views, you can optionally return a Blade template string from render().
For inline components like above, you should use the --inline flag during creation:
artisan make:livewire delete-post --inline
PROPERTIES

Introduction
Livewire components store and track data as public properties on the component class.

Public properties in Livewire are automatically made available to the view. No need to explicitly
pass them into the view (although you can if you want).

Important Notes
Here are three ESSENTIAL things to note about public properties before embarking on your
Livewire journey:
1. Property names can't conflict with property names reserved for Livewire (e.g. rules or
messages)
2. Data stored in public properties is made visible to the front-end JavaScript. Therefore, you
SHOULD NOT store sensitive data in them.
3. Properties can ONLY be either JavaScript-friendly data types (string, int, array,
boolean), OR one of the following PHP types: Stringable, Collection, DateTime,
Model, EloquentCollection.

protected and private properties DO NOT persist between Livewire updates. In


general, you should avoid using them for storing state.
You should also note that while null data type is Javascript-friendly, public properties
set to null DO NOT persist between Livewire updates.

Initializing Properties
You can initialize properties using the mount method of your component.

Livewire also makes a $this->fill() method available to you for cases where you have to set
lots of properties and want to remove visual noise.
Additionally, Livewire offers $this->reset() and $this->resetExcept() to programmatically
reset public property values to their initial state. This is useful for cleaning input fields after
performing an action.

Data Binding
If you've used front-end frameworks like Vue, or Angular, you are already familiar with this
concept. However, if you are new to this concept, Livewire can "bind" (or "synchronize") the
current value of some HTML element with a specific property in your component.
When the user types something into the text field, the value of the $message property will
automatically update.

Internally, Livewire will listen for an input event on the element, and when triggered, it will send
an AJAX request to re-render the component with the new data.

You can add wire:model to any element that dispatches an input event. Even custom
elements, or third-party JavaScript libraries.

Common elements to use wire:model on include:


Element Tag
<input type="text">

<input type="radio">

<input type="checkbox">

<select>

<textarea>
Binding Nested Data
Livewire supports binding to nested data inside arrays using dot notation:

Debouncing Input
By default, Livewire applies a 150ms debounce to text inputs. This avoids too many network
requests being sent as a user types into a text field.

If you wish to override this default (or add it to a non-text input), Livewire offers a "debounce"
modifier. If you want to apply a half-second debounce to an input, you would include the modifier
like so:

Lazy Updating
By default, Livewire sends a request to the server after every input event (or change in some
cases). This is usually fine for things like <select> elements that don't typically fire rapid updates,
however, this is often unnecessary for text fields that update as the user types.

In those cases, use the lazy directive modifier to listen for the native change event.

Now, the $message property will only be updated when the user clicks away from the input field.

Deferred Updating
In cases where you don't need data updates to happen live, Livewire has a .defer modifier that
batches data updates with the next network request.

For example, given the following component:


As the user types into the <input> field, no network requests will be sent. Even if the user clicks
away from the input field and onto other fields on the page, no requests will be sent.

When the user presses "Search", Livewire will send ONE network request that contains both the
new "query" state, AND the "search" action to perform.

This can drastically cut down on network usage when it's not needed.

Binding Directly To Model Properties


If an Eloquent model is stored as a public property on a Livewire component, you can bind to its
properties directly. Here is an example component:
Notice in the above component we are binding directly to the "title" and "content" model attributes.
Livewire will take care of hydrating and dehydrating the model between requests with the current,
non-persisted data.
Note: For this to work, you need to have a validation entry in the `$rules` property for
any model attributes you want to bind to. Otherwise, an error will be thrown.

Additionally, you can bind to models within an Eloquent Collection.


Livewire also supports binding to relationships on Eloquent models like so:
Custom (Wireable) Properties
Sometimes you may want to set a component property to a non-model object that's available inside
your app, like a DTO (Data Transfer Object).

For example, let’s say we have a custom object in our app called Settings. Rather than just store
settings data as a plain array on our Livewire component, we can attach associated behavior to this
data with a convenient wrapper object or DTO like Settings:
Now you can freely use this object as a public property of your component as long as that object
implements the Livewire\Wireable interface AND the property is typhinted like so:
And as you can see, changes to the component are persisted between requests because, with
Wireable, Livewire knows how to “dehydrate” and “re-hydrate” this property on your component.

If words like “hydrate” or “dehydrate” in the context of Livewire are fuzzy for you, give this
post a quick read.

Computed Properties
Livewire offers an API for accessing dynamic properties. This is especially helpful for deriving
properties from the database or another persistent store like a cache.
Now, you can access $this->post from either the component's class or Blade view:
Computed properties are cached for an individual Livewire request lifecycle. Meaning,
if you call `$this->post` 5 times in a component's blade view, it won't make a separate
database query every time.
ACTIONS

Introduction
The goal of actions in Livewire is to be able to easily listen to page interactions, and call a method
on your Livewire component (re-rendering the component).

Here's the basic usage:

Livewire currently offers a handful of directives to make listening to browser events trivial. The
common format for all of them is: wire:[dispatched browser event]="[action]".

Here are some common events you may need to listen for:
Event Directive
click wire:click
keydown wire:keydown
submit wire:submit
Here are a few examples of each in HTML:

You can listen for any event dispatched by the element you are binding to. Let's say
you have an element that dispatches a browser event called "foo", you could listen for
that event like so: <button wire:foo="someAction">

Like the above example using `wire:submit.prevent` directly at the form opening tag
will generate "readonly" properties for all html elements inside the form during the
requests.

Passing Action Parameters


You can pass extra parameters into a Livewire action directly in the expression like so:

Extra parameters passed to an action, will be passed through to the component's method as standard
PHP params:
Action parameters are also capable of directly resolving a model by its key using a type hint.

If your action requires any services that should be resolved via Laravel's dependency injection
container, you can list them in the action's signature before any additional parameters:

Event Modifiers
Like you saw in the keydown example, Livewire directives sometimes offer "modifiers" to add
extra functionality to an event. Below are the available modifiers that can be used with any event.
Modifier Description
stop Equivalent of event.stopPropagation()

prevent Equivalent of event.preventDefault()

self Only triggers an action if the event was triggered on itself. This prevents
outer elements from catching events that were triggered from a child
element. (Like often in the case of registering a listener on a modal
backdrop)
debounce.150ms Adds an Xms debounce to the handling of the action.
Keydown Modifiers
To listen for specific keys on keydown events, you can pass the name of the key as a modifier.
You can directly use any valid key names exposed via KeyboardEvent.key as modifiers by
converting them to kebab-case.

Here is a quick list of some common ones you may need:


Native Browser Event Livewire Modifier
Backspace backspace
Escape escape
Shift shift
Tab tab
ArrowRight arrow-right

In the above example, the handler will only be called if event.key is equal to 'PageDown'.

Magic Actions
In Livewire, there are some "magic" actions that are usually prefixed with a "$" symbol:
Function Description

$refresh Will re-render the component without firing any action

$set('property', Shortcut to update the value of a property


value)
$toggle('property') Shortcut to toggle boolean properties on or off

$emit('event', Will emit an event on the global event bus, with the provided params
...params)
$event A special variable that holds the value of the event fired that triggered
the action. Example usage:
wire:change="setSomeProperty($event.target.value)"
You can pass these as the value of an event listener to do special things in Livewire.

Let's take $set() for example. It can be used to manually set a component property's value.
Consider the Counter component's view.

Before

After

Notice that we are no longer calling the setMessageToHello function, we are directly specifying,
what we want data set to.

It can also be used in the backend when listening for an event. For example, if you have one
component that emits an event like this:

Then in another component you can use a magic action for example $refresh() instead of having
to point the listener to a method:
EVENTS

Introduction
Livewire components can communicate with each other through a global event system. As long as
two Livewire components are living on the same page, they can communicate using events and
listeners.

Firing Events
There are multiple ways to fire events from Livewire components.

From The Template

From The Component

From Global JavaScript

Event Listeners
Event listeners are registered in the $listeners property of your Livewire components.

Listeners are a key->value pair where the key is the event to listen for, and the value is the method
to call on the component.
Now when any other component on the page emits a postAdded event, this component will pick
it up and fire the incrementPostCount method on itself.

If the name of the event and the method you're calling match, you can leave out the
key. For example: protected $listeners = ['postAdded']; will call the
postAdded method when the postAdded event is emitted.

If you need to name event listeners dynamically, you can substitute the $listeners property for
the getListeners() protected method on the component:
getListeners() will only dynamically generate the names of listeners when the
component is mounted. Once the listeners are setup, these can't be changed.

Passing Parameters
You can also send parameters with an event emission.
Scoping Events

Scoping To Parent Listeners


When dealing with nested components, sometimes you may only want to emit events to parents
and not children or sibling components.

In these cases, you can use the emitUp feature:

Scoping To Components By Name


Sometimes you may only want to emit an event to other components of the same type.
In these cases, you can use emitTo:

(Now, if the button is clicked, the "postAdded" event will only be emitted to counter components)

Scoping To Self
Sometimes you may only want to emit an event on the component that fired the event.

In these cases, you can use emitSelf:

(Now, if the button is clicked, the "postAdded" event will only be emitted to the instance of the
component that it was emitted from.)

Listening For Events In JavaScript


Livewire allows you to register event listeners in JavaScript like so:
This feature is actually incredibly powerful. For example, you could register a listener
to show a toaster (popup) inside your app when Livewire performs certain actions. This
is one of the many ways to bridge the gap between PHP and JavaScript with Livewire.

Dispatching Browser Events


Livewire allows you to fire browser window events like so:

You are able to listen for this window event with JavaScript:

AlpineJS allows you to easily listen for these window events within your HTML:
LIFECYCLE HOOKS

Class Hooks
Each Livewire component undergoes a lifecycle. Lifecycle hooks allow you to run code at any
part of the component's lifecyle, or before specific properties are updated.
Hooks Description
boot Runs on every request, immediately after the component is instantiated, but
before any other lifecycle methods are called
booted Runs on every request, after the component is mounted or hydrated, but
before any update methods are called
mount Runs once, immediately after the component is instantiated, but before
render() is called. This is only called once on initial page load and never
called again, even on component refreshes
hydrate Runs on every subsequent request, after the component is hydrated, but
before an action is performed, or render() is called
hydrateFoo Runs after a property called $foo is hydrated
dehydrate Runs on every subsequent request, before the component is dehydrated, but
after render() is called
dehydrateFoo Runs before a property called $foo is dehydrated
updating Runs before any update to the Livewire component's data (Using
wire:model, not directly inside PHP)
updated Runs after any update to the Livewire component's data (Using
wire:model, not directly inside PHP)
updatingFoo Runs before a property called $foo is updated. Array properties have an
additional $key argument passed to this function to specify changing
element inside array, like updatingArray($value, $key)
updatedFoo Runs after a property called $foo is updated. Array properties have
additional $key argument as above
updatingFooBar Runs before updating a nested property bar on the $foo property or a
multiword property such as $fooBar or $foo_bar
updatedFooBar Runs after updating a nested property bar on the $foo property or a
multiword property such as $fooBar or $foo_bar

Please note that mutating a property directly inside a Livewire component class doesn't
trigger any of the updating/updated hooks.
Javascript Hooks
Livewire gives you the opportunity to execute javascript during certain events.
Hooks Description
component.initialized Called when a component has been initialized on the page by
Livewire
element.initialized Called when Livewire initializes an individual element
element.updating Called before Livewire updates an element during its DOM-diffing
cycle after a network roundtrip
element.updated Called after Livewire updates an element during its DOM-diffing
cycle after a network roundtrip
element.removed Called after Livewire removes an element during its DOM-diffing
cycle
message.sent Called when a Livewire update triggers a message sent to the server
via AJAX
message.failed Called if the message send fails for some reason
message.received Called when a message has finished its roudtrip, but before Livewire
updates the DOM
message.processed Called after Livewire processes all side effects (including DOM-
diffing) from a message
NESTING COMPONENTS

Introduction
Livewire supports nesting components. Component nesting can be an extremely powerful
technique, but there are a few gotchas worth mentioning up-front:
1. Nested components CAN accept data parameters from their parents, HOWEVER they are
not reactive like props from a Vue component.
2. Livewire components should NOT be used for extracting Blade snippets into separate files.
For these cases, Blade includes or components are preferable.

Here is an example of a nested component called add-user-note from another Livewire


component's view.
Keeping Track Of Components In A Loop
Similar to VueJs, if you render a component inside a loop, Livewire has no way of keeping track
of which one is which. To remedy this, livewire offers a special "key" syntax:

If you are on Laravel 7 or above, you can use the tag syntax.

Sibling Components in a Loop


In some situations, you may find the need to have sibling components inside of a loop, this situation
requires additional consideration for the wire:key value.

Each component will need its own unique wire:key, but using the method above will lead to both
sibling components having the same key, which will cause unforeseen issues. To combat this, you
could ensure that each wire:key is unique by prefixing it with the component name, for example:
COMPONENT FEATURES

VALIDATION

Introduction
Validation in Livewire should feel similar to standard form validation in Laravel. In short,
Livewire provides a $rules property for setting validation rules on a per-component basis, and a
$this->validate() method for validating a component's properties using those rules.

Here's a simple example of a form in Livewire being validated.


If validation fails, a standard ValidationException is thrown (and caught by Livewire), and the
standard $errors object is available inside the component's view. Because of this, any existing
code you have, likely a Blade include, for handling validation in the rest of your application will
apply here as well.

You can also add custom key/message pairs to the error bag.

If you need to define rules dynamically, you can substitute the $rules property for the rules()
method on the component:

Real-time Validation
Sometimes it's useful to validate a form field as a user types into it. Livewire makes "real-time"
validation simple with the $this->validateOnly() method.

To validate an input field after every update, we can use Livewire's updated hook:
Let's break down exactly what is happening in this example:
The user types into the "name" field
As the user types in their name, a validation message is shown if it's less than 6 characters
The user can switch to entering their email, and the validation message for the name still shows
When the user submits the form, there is a final validation check, and the data is persisted.

If you are wondering, "why do I need validateOnly? Can't I just use validate?". The reason is
because otherwise, every single update to any field would validate ALL of the fields. This can be
a jarring user experience. Imagine if you typed one character into the first field of a form, and all
of a sudden every single field had a validation message. validateOnly prevents that, and only
validates the current field being updated.

Validating with rules outside of the $rules property


If for whatever reason you want to validate using rules other than the ones defined in the $rules
property, you can always do this by passing the rules directly into the validate() and
validateOnly() methods.
Customize Error Message & Attributes
If you wish to customize the validation messages used by a Livewire component, you can do so
with the $messages property.

If you want to keep the default Laravel validation messages, but just customize the :attribute
portion of the message, you can specify custom attribute names using the
$validationAttributes property.
You can substitute the $messages property for the messages() method on the component.

If you are not using the global $rules validation property, then you can pass custom messages
and attributes directly into validate().
Direct Error Message Manipulation
The validate() and validateOnly() methods should handle most cases, but sometimes you
may want direct control over Livewire's internal ErrorBag.

Livewire provides a handful of methods for you to directly manipulate the ErrorBag.

From anywhere inside a Livewire component class, you can call the following methods:
Access Validator instance
Sometimes you may want to access the Validator instance that Livewire uses in the validate()
and validateOnly() methods. This is possible using the withValidator method. The closure
you provide receives the fully constructed validator as an argument, allowing you to call any of its
methods before the validation rules are actually evaluated.
Testing Validation
Livewire provides useful testing utilities for validation scenarios. Let's write a simple test for the
original "Contact Form" component.

This is useful, but we can take it one step further and actually test against specific validation rules:
Livewire also offers the inverse of assertHasErrors -> assertHasNoErrors():

For more examples of supported syntax for these two methods, take a look at the Testing Docs.

Custom validators
If you wish to use your own validation system in Livewire, that isn't a problem. Livewire will catch
ValidationException and provide the errors to the view just like using $this->validate().

For example:
You might be wondering if you can use Laravel's "FormRequest"s. Due to the nature
of Livewire, hooking into the http request wouldn't make sense. For now, this
functionality is not possible or recommended.
FILE UPLOADS

Basic Upload
Note: Your Livewire version must be >= 1.2.0 to use this feature.

Livewire makes uploading and storing files extremely easy.

First, add the WithFileUploads trait to your component. Now you can use wire:model on file
inputs as if they were any other input type and Livewire will take care of the rest.

Here's an example of a simple component that handles uploading a photo:


From the developer's perspective, handling file inputs is no different than handling any other input
type: Add wire:model to the <input> tag and everything else is taken care of for you.

However, there is more happening under the hood to make file uploads work in Livewire. Here's
a glimpse at what goes on when a user selects a file to upload:
1. When a new file is selected, Livewire's JavaScript makes an initial request to the
component on the server to get a temporary "signed" upload URL.
2. Once the URL is received, JavaScript then does the actual "upload" to the signed URL,
storing the upload in a temporary directory designated by Livewire and returning the new
temporary file's unique hash ID.
3. Once the file is uploaded and the unique hash ID is generated, Livewire's JavaScript makes
a final request to the component on the server telling it to "set" the desired public property
to the new temporary file.
4. Now the public property (in this case $photo) is set to the temporary file upload and is
ready to be stored or validated at any point.

Storing Uploaded Files


The previous example demonstrates the most basic storage scenario: Moving the temporarily
uploaded file to the "photos" directory on the app's default filesystem disk.

However, you may want to customize the file name of the stored file, or even specify a specific
storage "disk" to store the file on (maybe in an S3 bucket for example).
Livewire honors the same API's Laravel uses for storing uploaded files, so feel free to browse
Laravel's documentation. However, here are a few common storage scenarios for you:

The methods above should provide enough flexibility for storing the uploaded files exactly how
you want to.

Handling Multiple Files


Livewire handles multiple file uploads automatically by detecting the multiple attribute on the
<input> tag.

Here's an example of a file upload that handles multiple uploads:


File Validation
Like you've seen in previous examples, validating file uploads with Livewire is exactly the same
as handling file uploads from a standard Laravel controller.
Note: Many of the Laravel validation rules relating to files require access to the file. If you are
uploading directly to S3 these validation rules will fail if the object is not publicly accessible.

For more information on Laravel's File Validation utilities, visit the documentation.

Real-time Validation
It's possible to validate a user's upload in real-time, BEFORE they press "submit".

Again, you can accomplish this like you would any other input type in Livewire:
Now, when user selects a file (After Livewire uploads the file to a temporary directory) the file
will be validated and the user will receive an error BEFORE they submit the form.

Temporary Preview Urls


After a user chooses a file, you may want to show them a preview of that file BEFORE they submit
the form and actually store the file.

Livewire makes this trivial with the ->temporaryUrl() method on uploaded files.

Note: for security reasons, temporary urls are only supported for image uploads.

Here's an example of a file upload with an image preview:


Livewire stores temporary files in a non-public directory as previously mentioned, therefore,
there's no simple way to expose a temporary, public URL to your users for image previewing.

Livewire takes care of this complexity, by providing a temporary, signed URL that pretends to be
the uploaded image so that your page can show something to your users.

This URL is protected against showing files in directories above the temporary directory of course
and because it's signed temporarily, users can't abuse this URL to preview other files on your
system.

If you've configured Livewire to use S3 for temporary file storage, calling -


>temporaryUrl() will generate a temporary, signed URL from S3 directly so that you

don't hit your Laravel app server for this preview at all.

Testing File Uploads


Testing file uploads in Livewire is simple with Laravel's file upload testing helpers.

Here's a complete example of testing the "UploadPhoto" component with Livewire.


Here's a snippet of the "UploadPhoto" component required to make the previous test pass:

For more specifics on testing file uploads, reference Laravel's file upload testing documentation.

Uploading Directly To Amazon S3


As previously mentioned, Livewire stores all file uploads in a temporary directory until the
developer chooses to store the file permanently.

By default, Livewire uses the default filesystem disk configuration (usually local), and stores the
files under a folder called livewire-tmp/.

This means that file uploads are always hitting your server; even if you choose to store them in an
S3 bucket later.

If you wish to bypass this system and instead store Livewire's temporary uploads in an S3 bucket,
you can configure that behavior easily:
In your config/livewire.php file, set livewire.temporary_file_upload.disk to s3 (or
another custom disk that uses the s3 driver):

Now, when a user uploads a file, the file will never actually hit your server. It will be uploaded
directly to your S3 bucket, under the sub-directory: livewire-tmp/.

To configure this behavior, simply run the following artisan command from the environment that
has the S3 bucket configured.

Configuring Automatic File Cleanup


This temporary directory will fill up with files quickly, therefore, it's important to configure S3 to
cleanup files older than 24 hours.

Now, any temporary files older than 24 hours will be cleaned up by S3 automatically.

If you are not using S3, Livewire will handle the file cleanup automatically. No need to
run this command.

Loading Indicators
Although wire:model for file uploads works differently than other wire:model input types under
the hood, the interface for showing loading indicators remains the same.
You can display a loading indicator scoped to the file upload like so:

Now, while the file is uploading the "Uploading..." message will be shown and then hidden when
the upload is finished.

This works with the entire Livewire Loading States API.

Progress Indicators (And All JavaScript Events)


Every file upload in Livewire dispatches JavaScript events on the <input> element for custom
JavaScript to listen to.

Here are the dispatched events:


Event Description
livewire-upload- Dispatched when the upload starts
start
livewire-upload- Dispatches if the upload is successfully finished
finish
livewire-upload- Dispatches if the upload fails in some way
error
livewire-upload- Dispatches an event containing the upload progress percentage as
progress
the upload progresses

Here is an example of wrapping a Livewire file upload in an AlpineJS component to display a


progress bar:
JavaScript Upload API
Integrating with 3rd-party file-uploading libraries often requires finer-tuned control than a simple
<input type="file"> tag.

For these cases, Livewire exposes dedicated JavaScript functions.

The functions exist on the JavaScript component object, which can be accessed using the
convenience Blade directive: @this. If you haven't seen @this before, you can read more about it
here.
Configuration
Because Livewire stores all file uploads temporarily before the developer has a chance to validate
or store them, Livewire assumes some default handling of all file uploads.

Global Validation
By default, Livewire will validate ALL temporary file uploads with the following rules:
file|max:12288 (Must be a file less than 12MB).

If you wish to customize this, you can configure exactly what validate rules should run on all
temporary file uploads inside config/livewire.php:
Global Middleware
The temporary file upload endpoint has throttling middleware by default. You can customize
exactly what middleware this endpoint uses with the following configuration variable:

Temporary Upload Directory


Temporary files are uploaded to the livewire-tmp/ directory on the specified disk. You can
customize this with the following configuration key:
FILE DOWNLOADS

Introduction
Livewire supports triggering file downloads for users with a simple, intuitive API.

To trigger a file download, you can return a Laravel file download from any component action.

Livewire should handle any file download that Laravel would. Here are a few other utilities you
might use:
Testing File Downloads
Testing file downloads is simple with livewire.

Here is an example of testing the component above and making sure the export was downloaded.
QUERY STRING

Introduction
Sometimes it's useful to update the browser's query string when your component state changes.

For example, if you were building a "search posts" component, and wanted the query string to
reflect the current search value like so:
https://your-app.com/search-posts?search=some-search-string

This way, when a user hits the back button, or bookmarks the page, you can get the initial state out
of the query string, rather than resetting the component every time.

In these cases, you can add a property's name to protected $queryString, and Livewire will
update the query string every time the property value changes, and also update the property when
the query string changes.
Keeping A Clean Query String
In the case above, when the search property is empty, the query string will look like this:
?search=

There are other cases where you might want to only represent a value in the query string if it is
NOT the default setting.

For example, if you have a $page property to track pagination in a component, you may want to
remove the page property from the query string when the user is on the first page.

In cases like these, you can use the following syntax:


Query String Aliases
Additionally, if you want to modify how properties are represented in the URL, Livewire offers a
simple syntax for aliasing query strings.

For example, if you want to shorten the URL, where the page property is represented as p and
search as s, you can use the as modifier to achieve that outcome.
Now the URL can look like this:
?s=Livewire%20is%20awesome&p=2
AUTHORIZATION

Introduction
To authorize actions in Livewire, you can use the AuthorizesRequests trait in any component,
then call $this->authorize() like you normally would inside a controller. For example:

If you use a different guard to authenticate your users then also add an entry to middleware_group
in the livewire config file:
PAGINATION

Introduction
Livewire offers the ability to paginate results within a component. This feature hooks into Laravel's
native pagination features, so it should feel like an invisible feature to you.

Paginating Data
Let's say you have a show-posts component, but you want to limit the results to 10 posts per page.

You can paginate the results by using the WithPagination trait provided by Livewire.
Now there will be rendered HTML links for the different pages at the bottom of your posts, and
the results will be paginated.

Resetting Pagination After Filtering Data


A common pattern when filtering a paginated result set is to reset the current page to "1" when
filtering is applied.

Livewire's WithPagination trait exposes a ->resetPage() method to accomplish this.

This method can be used in combination with the updating/updated lifecycle hooks to reset the
page when certain component data is updated.

An optional page name parameter may be passed through, if the pagination name is set to anything
other than page.
Multiple paginators on the same page
Because Livewire hardcodes the $page property inside the WithPagination trait, there is no way
to have two different paginators on the same page because each will be competing for the same
property name in the query string of the URL bar.

Here’s an example of two different components that might exist on the same page. By giving the
second one (the comments one) a name, Livewire will pick it up and handle everything
accordingly.
Now in the query string, both paginators will be represented like so:

To reset a specific paginator, you may pass through your custom page name using the -
>resetPage() method as found in the WithPagination trait.

Using The Bootstrap Pagination Theme


Like Laravel, Livewire's default pagination view uses Tailwind classes for styling. If you use
Bootstrap in your application, you can enable the Bootstrap theme for the pagination view using
the $paginationTheme property on your component.
Using A Custom Pagination View
Livewire provides 3 ways to customize the pagination links Blade view, rendered when calling
$results->links().

Method A: Pass view name directly to the ->links() method.

Method B: Override the paginationView() method in your component.


Method C: Publish the Livewire pagination views.
You can publish the Livewire pagination views to resources/views/vendor/livewire using
the following artisan command:

Unfortunately, Livewire will overwrite a custom view you have defined inside a service
provider using: Paginator::defaultView().

When using either method, instead of anchor tags in your pagination component, you should use
wire:click handlers with the following methods:

nextPage to navigate to the next page

previousPage to navigate to the previous page

gotoPage($page) to navigate to a specific page.


See below for an example of how the default livewire paginator works.
REDIRECTING

Introduction
You may want to redirect from inside a Livewire component to another page in your app. Livewire
supports the standard redirect response syntax you are used to using in Laravel controller.

Now, after the user clicks "Submit" and their contact is added to the database, they will be
redirected to the success page (/contact-form-success).

Because Livewire works with Laravel's redirection system, you can use any notation
you are used to like redirect('/foo'), redirect()->to('/foo'), redirect()-
>route('foo').
FLASH MESSAGES

Introduction
In cases where it's useful to "flash" a success or failure message to the user, Livewire supports
Laravel's system for flashing data to the session.

Here's a common example of its usage:


Now, after the user clicks "Save" and their post is updated, they will see "Post successfully
updated" on the page.

If you wish to add flash data to a redirect and show the message on the destination page instead,
Livewire is smart enough to persist the flash data for one more request. For example:
Now when a user "Saves" a post, they will be redirected to the "/posts" endpoint and see the flash
message there. This assumes the /posts page has the proper Blade snippet to display flash
messages.
TRAITS

Introduction
PHP Traits are a great way to re-use functionality between multiple Livewire components.

For example, you might have multiple "data table" components in your application that all share
the same logic surrounding sorting.

Rather than duplicating the following sorting boilerplate in every component:


You could instead extract this behavior into a re-usable trait called WithSorting:
Additionally, if you want to use Livewire's lifecycle hooks inside your traits but still be able to use
them inside your component, Livewire offers a syntax that allows you to do this:
Livewire offers hooks for query strings as well.
Note that you are allowed to override any query string in your component class.
UI NICETIES

LOADING STATES

Introduction
Because Livewire makes a roundtrip to the server every time an action is triggered on the page,
there are cases when the page may not react immediately to a user event (like a click). Livewire
allows you to easily display loading states, which can make your app feel more responsive.

Toggling elements during "loading" states


Elements with the wire:loading directive are only visible while waiting for actions to complete
(network requests).

When the "Checkout" button is clicked, the "Processing Payment..." message will show. When the
action is finished, the message will disappear.

By default, Livewire set's a loading element's "display" CSS property to "inline-block". If you
want Livewire to use "flex" or "grid", you can use the following modifiers.
You can also "hide" an element during a loading state using the .remove modifier.

Delaying loading indicator


If you want to avoid flickering because loading is very fast, you can add the .delay modifier, and
it will only show up if loading takes longer than 200ms.

If you wish, you can customize the delay duration with the following modifiers:
Targeting specific actions
The method outlined above works well for simple components. For more complex components,
you may want to show loading indicators only for specific actions.

In the above example, the loading indicator will be displayed when the "Checkout" button is
clicked, but not when the "Cancel" button is clicked.

wire:target can accept multiple arguments in a comma separated format like this:
wire:target="foo, bar".

You may also target actions with specific parameters.

If you wish to trigger a loading indicator when ANY of the properties of an array change, you can
simply target the entire array:
Targeting models
In addition to actions, you can also target whenever a wire:model is synchronized.

Toggling classes
You can add or remove classes from an element during loading states, by adding the .class
modifier to the wire:loading directive.
Now, when the "Checkout" button is clicked, the background will turn gray while the network
request is processing.

You can also perform the inverse and remove classes by adding the .remove modifier.

Now the bg-blue class will be removed from the button while loading.

Toggling attributes
Similar to classes, HTML attributes can be added or removed from elements during loading states:

Now, when the "Checkout" button is clicked, the disabled="true" attribute will be added to the
element while loading.
POLLING

Introduction
Livewire offers a directive called wire:poll that, when added to an element, will refresh the
component every 2s.

Polling for changes over Ajax is a lightweight, simpler alternative to something like
Laravel Echo, Pusher, or any WebSocket strategy.

You can customize the frequency by passing a directive modifier like 750ms. For example:

You can also specify a specific action to fire on the polling interval by passing a value to
wire:poll:

Now, the foo method on the component will be called every 2 seconds.
Polling in the background
Livewire reduces polling when the browser tab is in the background so that it doesn't bog down
the server with ajax requests unnecessarily. Only about 5% of the expected polling requests are
kept.

If you'd like to keep polling at the normal rate even while the tab is in the background, you can use
the keep-alive modifier:

Polling only when element is visible


If your component isn't always visible in the browser's viewport (further down the page for
example), you can opt to only poll the server when an element is visible by adding the .visible
modifier to wire:poll. For example:
PREFETCHING

Introduction
Livewire offers the ability to "prefetch" the result of an action on mouseover. Toggling display
content is a common use case.

This is useful for cases when an action DOES NOT (like writing to session or
database) perform side effects. If the action you are "pre-fetching" has side-effects,
the side-effects will be unpredictably executed.

Add the prefetch modifier to an action to enable this behavior:

Now, when the mouse enters the "Show Content" button, Livewire will fetch the result of the
"toggleContent" action in the background. If the button is actually clicked, it will display the
content on the page without sending another network request. If the button is NOT clicked, the
prefetched response will be thrown away.
OFFLINE STATE

Introduction
It's sometimes important to notify a user if they have lost their internet connection. Livewire
provides helpful utilities to perform actions based on a user's "offline" state.

Toggling elements
You can show an element on the page when the user goes "offline", by adding the wire:offline
attribute.

This <div> will automatically be hidden by default, and shown to the user when the browser goes
offline.

Toggling classes
Adding the class modifier allows you to add a class to an element when "offline".

Now, when the browser goes offline, the element will receive the bg-red-300 class. The class will
be removed again once the user is back online.

You can also perform the inverse, and remove classes by adding the .remove modifier, similar to
how wire:loading works.
The bg-green-300 class will be removed from the <div> while offline.

Toggling attributes
Adding the attr modifier allows you to add an attribute to an element when "offline".

Now, when the browser goes offline, the button will be disabled.

You can also perform the inverse, and remove attributes by adding the .remove modifier.
DIRTY STATES

Introduction
There are cases where it may be useful to provide feedback that content has changed and is not yet
in-sync with the back-end Livewire component.

For input that uses wire:model, or wire:model.lazy, you may want to display that a field is
'dirty' until Livewire has fully updated.

Toggling classes on "dirty" elements


Elements with the wire:dirty directive will watch for differences between the front-end value,
and the last returned Livewire data value.

Adding the class modifier allows you to add a class to the element when dirty.

Now, when a user modifies the input value, the element will receive the border-red-500 class.
The class will be removed again if the input value returns to its original state, or if the Livewire
component updates.

You can also perform the inverse, and remove classes by adding the .remove modifier, similar to
how wire:loading works.

The bg-green-200 class will be removed from the input while dirty.
Toggling elements
The default behaviour of the wire:dirty directive without modifiers is that the element will be
hidden until dirty. This can create a paradox if used on the input itself, but like loading states, the
dirty directive can be used to toggle the appearance of other elements using wire:target.

In this example, the span will be hidden by default, and only visible when the input element is
dirty.

Toggling classes on other elements


The class and attribute modifiers can be used in the same way for referenced elements

Now, when the input is dirty, the label text will receive the text-red-500 class.
DEFER LOADING

Introduction
Livewire offers a wire:init directive to run an action as soon as the component is rendered. This
can be helpful in cases where you don't want to hold up the entire page load, but want to load some
data immediately after the page load.
The loadPosts action will be run immediately after the Livewire component renders on the page.
JS INTEGRATIONS

ALPINEJS

Introduction
There are lots of instances where a page interaction doesn't warrant a full server-roundtrip, like
toggling a modal.

For these cases, AlpineJS is the perfect companion to Livewire.

It allows you to sprinkle JavaScript behavior directly into your markup in a declarative/reactive
way that should feel very similar to VueJS (If that's what you're used to).

Installation
You must install Alpine in order to use it with Livewire.

To install Alpine in your project, add the following script tag to the <head> section of your layout
file.

For more installation information, visit the Alpine Docs.

Using Alpine Inside Of Livewire


Here's an example of using AlpineJS for "dropdown" functionality INSIDE a Livewire
component's view.
Extracting Reusable Blade Components
If you are not already used to each tool on its own, mixing the syntaxes of both can be a bit
confusing.

Because of this, when possible, you should extract the Alpine parts to reusable Blade components
for consumption inside of Livewire (and anywhere in your app).

Here is an example (Using Laravel 7 Blade component tag syntax).

The Livewire View:


The Reusable "dropdown" Blade Component:

Now, the Livewire and Alpine syntaxes are completely separate, AND you have a reusable Blade
component to use from other components.

Interacting With Livewire From Alpine: $wire


From any Alpine component inside a Livewire component, you can access a magic $wire object
to access and manipulate the Livewire component.
To demonstrate its usage, we'll create a "counter" component in Alpine that uses Livewire
completely under the hood:

Now, when a user clicks "Increment", the standard Livewire round trip will trigger and Alpine will
reflect Livewire's new $count value.

Because $wire uses a JavaScript Proxy under the hood, you are able to access properties on it and
call methods on it and those operations will be forwarded to Livewire. In addition to this
functionality, $wire also has standard, built-in methods available to you.

Here is the full API for $wire:


Sharing State Between Livewire And Alpine: @entangle
Livewire has an incredibly powerful feature called "entangle" that allows you to "entangle" a
Livewire and Alpine property together. With entanglement, when one value changes, the other
will also be changed.
To demonstrate, consider the dropdown example from before, but now with its showDropdown
property entangled between Livewire and Alpine. By using entanglement, we are now able to
control the state of the dropdown from both Alpine AND Livewire.

Now a user can toggle on the dropdown immediately with Alpine, but when they click a Livewire
action like "Archive", the dropdown will be told to close from Livewire. Both Alpine and Livewire
are welcome to manipulate their respective properties, and the other will automatically update.
Sometimes, it isn't necessary to update Livewire on every Alpine change, and you'd rather bundle
the change with the next Livewire request that goes out. In these cases, you can chain on a .defer
property like so:

Now, when a user toggles the dropdown open and closed, there will be no AJAX requests sent for
Livewire, HOWEVER, when a Livewire action is triggered from a button like "archive" or
"delete", the new state of "showDropdown" will be bundled along with the request.

If you are having trouble following this difference. Open your browser's devtools and observe the
difference in XHR requests with and without .defer added.

Using the @js directive


If ever you need to output PHP data for use in Alpine, you can now use the @js directive.

Accessing Livewire Directives From Blade Components


Extracting re-usable Blade components within your Livewire application is an essential pattern.

One difficulty you might encounter while implementing Blade components within a Livewire
context is accessing the value of attributes like wire:model from inside the component.

For example, you might create a text input Blade component like so:
A simple Blade component like this will work perfectly fine. Laravel and Blade will automatically
forward any extra attributes added to the component (like wire:model in this case), and place
them on the <input> tag because we echoed out the attribute bag ($attributes).

However, sometimes you might need to extract more detailed information about Livewire
attributes passed to the component.

For these cases, Livewire offers an $attributes->wire() method to help with these tasks.

Given the following Blade Component usage:

You could access Livewire directive information from Blade's $attribute bag like so:

You can also "forward" these Livewire directives individually. For example:
There are LOTS of different ways to use this utility, but one common example is using it in
conjunction with the aforementioned @entangle directive:

Note: If the .defer modifier is passed via wire:model.defer, the @entangle directive will
automatically recognize it and add the @entangle('...').defer modifier under the hood.
Creating A DatePicker Component
A common use case for JavaScript inside Livewire is custom form inputs. Things like datepickers,
color-pickers, etc... are often essential to your app.

By using the same pattern above, (and adding some extra sauce), we can utilize Alpine to make
interacting with these types of JavaScript components a breeze.

Let's create a re-usable Blade component called date-picker that we can use to bind some data
to in Livewire using wire:model.

Here's how we will be using it:

For this component we will be using the Pikaday library.

According to the docs, the most basic usage of the package (after including the assets) looks like
this:
All you need is an <input> element, and Pikaday will add all the extra date-picker behavior for
you.

Now let's see how we might write a re-usable Blade component for this library.

The date-picker Reusable Blade Component:

Note: The {{ $attributes }} expression is a mechanism in Laravel 7 and above to forward extra
HTML attributes declared on the component tag.

Forwarding wire:model input Events


Under the hood, wire:model adds an event listener to update a property every time the input
event is dispatched on or under the element. Another way to communicate between Livewire and
Alpine is by using Alpine to dispatch an input event with some data within or on an element with
wire:model on it.

Let's create a contrived example where when a user clicks the first button a property called $foo
is set to bar, and when a user clicks the second button, $foo is set to baz.

Within A Livewire Component's View:


A more real-world example would be creating a "color-picker" Blade component that might be
consumed inside a Livewire component.

Color-picker Component Usage:

For the component definition, we will be using a third-party color-picker lib called Vanilla Picker.

This sample assumes you have it loaded on the page.

Color-picker Blade Component Definition (Un-commented):


Color-picker Blade Component Definition (Commented):
Ignoring DOM-changes (using wire:ignore)
Fortunately a library like Pikaday adds its extra DOM at the end of the page. Many other libraries
manipulate the DOM as soon as they are initialized and continue to mutate the DOM as you interact
with them.

When this happens, it's hard for Livewire to keep track of what DOM manipulations you want to
preserve on component updates, and which you want to discard.
To tell Livewire to ignore changes to a subset of HTML within your component, you can add the
wire:ignore directive.

The Select2 library is one of those libraries that takes over its portion of the DOM (it replaces your
<select> tag with lots of custom markup).

Here is an example of using the Select2 library inside a Livewire component to demonstrate the
usage of wire:ignore.

Also, note that sometimes it's useful to ignore changes to an element, but not its
children. If this is the case, you can add the self modifier to the wire:ignore
directive, like so: wire:ignore.self.
LARAVEL ECHO

Introduction
Livewire pairs nicely with Laravel Echo to provide real-time functionality on your web-pages
using WebSockets.

This feature assumes you have installed Laravel Echo and the `window.Echo` object is
globally available. For more info on this, check out the docs.

Consider the following Laravel Event:

Let's say you fire this event with Laravel's broadcasting system like this:

Normally, you would listen for this event in Laravel Echo like so:
Listeners
With Livewire all you have to do is register it in your $listeners property, with some special
syntax to designate that it originates from Echo.

If you have Echo channels with variables in (such as a Order ID) you can use the getListeners()
function instead of the $listeners array.
getListeners() will only dynamically generate the names of listeners when the
component is mounted. Once the listeners are setup, these can't be changed.

Now, Livewire will intercept the received event from Pusher, and act accordingly.

Private & Presence Channels


In a similar way to regular public channels, you can also listen to events broadcasted to private
and presence channels:

Make sure you have your Authentication Callbacks properly defined.


This gives you the ability to react to a listen event on those channels with the OrderShipped event
name. You can also access the joining | leaving | here events of a presence channels with a
slight change to the syntax.
INLINE SCRIPTS

Introduction
Livewire recommends that you use AlpineJS for most of your JavaScript needs, but it does support
using <script> tags directly inside your component's view.

Please note that your scripts will be run only once upon the first render of the
component. If you need to run a JavaScript function later - emit the event from the
component and listen to it in JavaScript as described here)

You can also push scripts directly onto Blade stacks from your Livewire component:

Using the @js directive


If ever you need to output PHP data for use in Javascript, you can now use the @js directive.
Accessing the JavaScript component instance
Because Livewire has both a PHP AND a JavaScript portion, each component also has a JavaScript
object. You can access this object using the special @this blade directive in your component's
view.

Here's an example:

Note: the @this directive compiles to the following string for JavaScript to interpret:
"Livewire.find([component-id])"
TESTING

Introduction
Livewire offers a powerful set of tools for testing your components.

Here's a Livewire component and a corresponding test to demonstrate the basics.


Testing Component Presence
Livewire registers handy PHPUnit methods for testing a components presence on a page.

Alternatively, you may pass a component's class name to the assertSeeLivewire and
assertDontSeeLivewire methods.
Testing With Query String Parameters
To test Livewire's $queryString functionality, you can use Livewire's ::withQueryParams
testing utility.
Testing Components With Passed Data

Generating Tests
When creating a component, you can include the --test flag, and a test file will be created for
you as well.
All Available Test Methods
DEPLOYMENT

Livewire Changes
Occasionally there will be changes to Livewire's internal method signatures that will require a
refresh of any components currently running in the browser (we try to keep these to a minimum).

To achieve this, Livewire uses an internal deployment hash and keeps track of whether it has
changed or not.

If Livewire's deployment hash has changed, it will trigger the page expired dialog or hook.

Page Expired Dialog and Hook

Page Expired Dialog


By default, if a deployment hash doesn't match (see above) or a users session has expired, then
Livewire will display a confirmation dialog prompting the user to refresh the page.
Page Expired Hook
If the default page expired dialog isn't suitable, you can implement a custom solution for notifying
users, by using the page expired hook.

To do this you would pass a javascript callback to Livewire.onPageExpired() that handles


notifying your users.

You could dispatch a browser event from the page expired callback, that Alpine could
listen for to show a custom dialog modal prompting users to refresh their page.

You need to either place the Livewire.onPageExpired() call after Livewire's scripts in your
layout file

Or wrap it in an event listener that waits for Livewire to load


SECURITY

Introduction
To the new Livewire developer, the experience is somewhat magical. It feels as if when the page
loads, your Livewire component is living on a server listening for updates from the browser and
responding to them in real-time.

This is not far from how other, similar tools like Phoenix LiveView work.

However much Livewire feels similar, it has quite different inner-workings that have their own
sets of pros, cons, and security implications.

Livewire components feel "stateFULL", however, they are completely "stateLESS". There is no
long-running Livewire instance on the server waiting for browser interactions. Each interaction is
an entirely new and fresh request/response.

To more fully grasp this mental model, let's use the following simple "counter" component as a
starting point.
The experience of using this "counter" from a user's perspective goes like this: A user loads the
page, sees the number "1", clicks the "+" button, and now sees the number "2".

Below is a visualization of how Livewire actually works to achieve this effect.


To summarize, when a user visits the page containing the "counter" component, a normal request
is sent to the server like any other page. That page renders the initial view of the "counter" like any
normal Blade component, however, in addition to rendering HTML, Livewire "dehydrates" or
"serializes" the component's state (public properties) and passes it to the front-end.

Now that the front-end has the component state, when an update is triggered (clicking the "+" in
this case), a request is sent to the server INCLUDING the last-known component state. The server
"hydrates" or "deserializes" the component from that state and performs any updates.

The component is now dehydrated again to provide the browser with the newly rendered HTML
and the updated state for use in later interactions requests.

Here is a deeper visualization of the actual component lifecycles during these requests.
Hopefully now you've adopted a more accurate mental model of how Livewire works under the
hood. This will allow you to more intelligently debug problems and understand the performance
and security implications of using Livewire.

Security Measures
Like you learned above, each Livewire request is "stateless" in the sense that there is no long-
running server instance maintaining state. The state is stored in the browser and passed back and
forth to the server between requests.

Because the state is stored in the browser, it is vulnerable to front-end manipulation. Without
security measures in place, it would not be difficult for a malicous person to manipulate the state
of a component in the browser between requests.
In our "counter" example, there are no real negative implications of manipulating something as
trivial and ephemeral as the "count" of that component, but in a component with more at stake, for
example an "edit post" component with a delete button, security measures need to be in place.

The Checksum
The fundamental security underpinning Livewire is a "checksum" that travels along with
request/responses and is used to validate that the state from the server hasn't been tampered with
in the browser.

o further explain, consider the "counter" component above. Rather than simply passing { count:
1 } to the browser, Livewire will generate a hash (checksum) of that payload using a secure key
and pass it along with the state.

A more realistic representation of the Livewire payload for the "counter" would look something
like this:

Now if a malicous person tampered with the state in the browser between requests, before Livewire
handled a component update, it would see that a hash of the payload doesn't match the checksum
and throw an error.

Persistent Middleware
The second security measure Livewire puts in place is "persistent middleware". This means
Livewire will capture any authentication/authorization middleware that was used during the
"Initial Request" and re-apply it to subsequent requests.
Without this measure, a Livewire subsequent request could be captured and re-played after a user
has been logged out of the application and should no longer have access to those code paths.

By default, Livewire re-applies the out-of-the-box authentication and authorization middlewares


that ship with every Laravel app. Here are a couple of the defaults:

If you wish to add your own middlewares to be captured and re-applied if present, you can do so
in your app's service provider with the following API:

Now any middlewares you added will be re-applied to subsequent Livewire requests IF the
middleware is assigned to the original route the component was loaded on.
TROUBLESHOOTING

Dom Diffing Issues


The most common issues encountered by Livewire users has to do with Livewire's DOM
diffing/patching system. This is the system that selectively updates elements that have been
changed, added, or removed after every component update.

For the most part, this system is reliable, but there are certain cases where Livewire is unable to
properly track changes. When this happens, hopefully, a helpful error will be thrown and you can
debug with the following guide.

Symptoms
• An input element loses focus
• An element or group of elements dissapears suddenly
• A previously interactive element stops responding to user input
• A loading indicator mis-fires
• A user action no longer functions

Cures
Ensure your component has a single-level root element

Add wire:key to elements inside loops (the value to wire:key must be unique across the page):

Add key()/wire:key to nested components in a loop


Wrap Blade conditionals (@if, @error, @auth) in an element

Add wire:key. As a final measure, adding wire:key will directly tell Livewire how to keep track
of a DOM element. Over-using this attribute is a smell, but it is very useful and powerful for
problems of this nature.

The value you pass to wire:key must be entirely unique to that page. Meaning that
you should prefix it, like wire:key="item-{{ $item->id }}", and avoid using
$loop->index to track the individual elements where you can.

Checksum Issues
On every request, Livewire does a "checksum" but in some cases with arrays, it can throw an
exception even when the data inside the array is the same.
Because in PHP an array can have keys that are alpha-numeric and numeric keys in the same array
and in any order, but Javascript will make an object of it because it doesn't support arrays with
keys that are alpha-numeric. When Javascript is creating an object it will also reorder the keys, it
will place numeric keys before alpha-numeric keys.

This causes a problem when the JSON is sent back because the "checksum" will look different.

Some types (Point, LineString, Polygon, and the Multi- variations) will also fail this checksum.

So make sure when you have a public property that is an array numeric keys are before alpha-
numeric character keys.

Query String Issues


Livewire is using the site's referrer information when setting the query string. This can lead to
conflicts when you are adding security headers to your application through the referrer-policy.

Symptoms
• The query string does not get updated at all.
• The query string does not get updated when the value is empty.

Cures
If you do set security headers, make sure the referrer-policy value is set to same-origin.
Root Element Issues
Livewire requires that there be only one HTML element at the root of a components blade view.

Having multiple root elements can mean that parts of your view won't work with Livewire
correctly, if at all.

Symptoms
A button isn't triggering a wire:click

Entering data into an input doesn't trigger a network request

Parts of your view aren't updating properly (could also be a Dom Diffing issue, see above)

You get an error in your browser console that says Livewire: Multiple root elements
detected. This is not supported.

See below for an example of a component with a button that doesn't work:

Cures
The solution is to ensure that you only have one root HTML element, such as a <div>. If you have
multiple elements, then wrap everything in a <div> or another element that suits your layout.

So in our example from above, we have wrapped everything in a <div> which gets the button
running:
Another cause can be using __construct() inside the Livewire class or a Trait.
PACKAGE DEVELOPMENT

Registering Custom Components


You may manually register components using the Livewire::component method. This can be
useful if you want to provide Livewire components from a composer package. Typically this
should be done in the boot method of a service provider.

Now, applications with your package installed can consume your component in their views like
so:
ARTISAN COMMANDS

The make command

Once created, you can render your components in a Blade file with the @livewire('component-
name') blade directive.

Think of Livewire components like Blade includes. You can insert @livewire anywhere in a Blade
view and it will render.
If you are on Laravel 7 or greater, you can use the tag syntax.

Modifying Stubs
You can customize the stubs (templates) that Livewire uses to create new component classes and
views using the livewire:stubs command.

The above command will create three files:


stubs/livewire.stub

stubs/livewire.view.stub

stubs/livewire.inline.stub

Now, when you run the make:livewire command, Livewire will use the above stub files as the
template.

The move Command


The php artisan livewire:move command will move/rename the component class, blade view
and the component test if it exists, taking care of namespaces and paths

Here is an example of usage:


For convenience, livewire:move is aliased to livewire:mv

The copy Command


The php artisan livewire:copy command will create copies of the component class and blade
view, taking care of namespaces and paths

Here are a few examples of usage:

For convenience, livewire:copy is aliased to livewire:cp

The delete Command


The php artisan livewire:delete command will remove the component class and blade view.

Here are a few examples of usage:


For convenience, livewire:delete is aliased to livewire:rm
CONTRIBUTION GUIDE

Introduction
At Livewire we appreciate and welcome all contributions!

If that's something you would be interested in doing, we recommend going through this
contribution guide first before starting.

Setup Livewire locally


The first step is to create a fork of Livewire and set it up locally. You should only need to do this
the first time.

Fork Livewire
Go to the Livewire repository on GitHub and fork the Livewire repository.

Git clone your fork locally


Browse to your fork on GitHub, and click on the "code" button, and copy the provided URL.
Then in your local terminal run git clone and pass it your URL and the directory name you want
Livewire cloned into.

Once finished, cd into your local Livewire directory.

Install dependencies
Install composer dependencies by running:

Install npm dependencies by running:


Configure dusk
A lot of Livewire's tests make use of orchestral/testbench-dusk which runs browser tests in
Google Chrome (so you will need Chrome to be installed).

To get orchestral/testbench-dusk to run, you need to install the latest chrome driver by
running:

Run tests
Once everything is configured, run all tests to make sure everything is working and passing.

To do this, run phpunit and confirm everything is running ok.

If the dusk tests don't run and you get an error, make sure you have run the command in the
Configure dusk section above.

If you still get an error, the first time you try to run dusk tests, you may also need to close any
Google Chrome instances you may have open and try running the tests again. After that, you should
be able to leave Chrome open when running tests.

Bug fix/ feature development


Now it's time to start working on your bug fix or new feature.
Create a branch
To start working on a new feature or fix a bug, you should always create a new branch in your fork
with the name of your feature or fix.

Always create a new branch for your feature or fix.

Do not use your master/ main branch of your fork as maintainers cannot modify PR's submitted
from a master/main branch on a fork.

Any PR's submitted from a master/main branch will be closed.

Add failing tests


The next step is to add failing tests for your code.

Livewire has both Dusk browser tests and standard PHPUnit unit tests, which you can find in
tests/Browser and tests/Unit respectively.

Livewire runs both PHP and Javascript code, so Dusk browser tests are preferred to ensure
everything works as expected, and can be supported with unit tests as required.

See below for an example of how a Livewire Dusk test should be structured:
You can see how to use Dusk in the Laravel documentation as well as look at Livewire's existing
browser tests for further examples.

Add working code


Livewire has both PHP and javascript code, which you can find in the src directory for PHP and
the js directory for javascript.

Change the code as required to fix the bug or add the new feature, but try to keep changes to a
minimum. Consider splitting into multiple PR's if required.

PR's that make too many changes or make unrelated changes may be closed.

If you have updated any of Livewire's javascript code, you will need to recompile the assets. To
do this run npm run build, or you may start a watcher with npm run watch.

Compiled javascript assets should be committed with your changes.

If you update any javascript, make sure to recompile assets and commit them.
Once you have finished writing your code, do a review to ensure you haven't left any debugging
code and formatting matches the existing style.

Run tests
The final step before submitting is to run all tests to ensure your changes haven't impacted anything
else.

To do this, run phpunit and confirm everything is running ok.

If the Dusk browser tests don't run, see Run tests in the Setup section above for more details

Submit PR
Once all tests pass, then push your branch up to GitHub and submit your PR.

In your PR description make sure to provide a small example of what your PR does along with a
thorough description of the improvement and reasons why it's useful. Add links to any issues or
discussions that are relevant for further details.

For first-time contributors, tests won't run automatically, so they will need to be started
by a maintainer.

Thanks for contributing!


And that's it!

Maintainers will review your PR and give feedback as required.

Thanks for contributing to Livewire!

You might also like