Litewire


Getting Started

Litewire is Zap's lightweight browser-side interaction layer. It is loaded by default and scans the page for request directives, reactive state, input models, expressions, and JavaScript components. When Litewire replaces or inserts response markup, it scans the updated content too.

Directive names beginning with lw- handle server requests. Directives beginning with lw: handle client-side state and DOM behavior.

Reactive State

Put lw:state on a container and initialize it with a JavaScript object. Use lw:click to update the state, lw:text to display an expression, and lw:show to conditionally show an element.

<div lw:state="{ count: 0 }">
 <button type="button" lw:click="count--">−</button>
 <span lw:text="count"></span>
 <button type="button" lw:click="count++">+</button>
 <p lw:show="count >= 5">Five or more</p>
</div>
0

Assignments and deletions of top-level state properties trigger a render of the state container. The render updates its lw:text and lw:show descendants.

Binding Input Models

Bind a field with lw:model. A regular model updates on input; lw:model.change updates on change, and lw:model.blur updates on blur. Use a model name matching a property in the nearest state container to keep that state in sync.

<div lw:state="{ name: 'Ada' }">
 <input class="form-control" value="Ada" lw:model="name">
 <p>Hello, <span lw:text="name"></span>!</p>
</div>

Hello, Ada!

Models can also update a DOM target by using a selector as the model value, for example lw:model="#preview". Without a state container or target selector, the value is stored in Litewire's global models object.

Server Requests

Use lw-get, lw-post, lw-put, or lw-delete to request a URL. By default, buttons are triggered by click and forms by submit. Set lw-trigger to use another DOM event, or set it to load to request as soon as the element is scanned.

<form lw-post="/profile" lw-target="#profile-result" lw-swap="innerHTML">
 <input class="form-control" name="display_name">
 <button type="submit">Save</button>
 <span class="litewire-indicator" hidden>Saving…</span>
</form>
<div id="profile-result"></div>

GET requests include form data as query parameters. POST, PUT, and DELETE requests send form data as FormData. If a CSRF meta token is present, Litewire sends it in the X-CSRF-TOKEN header. The server response is treated as HTML and swapped into the target.

Use lw-target to choose the destination (the requesting element is the default) and lw-swap to choose how to insert the response: innerHTML (default), outerHTML, append, or prepend. Use lw-push-url to add a URL to browser history; its value can be true to use the request URL or a URL string to set a specific one.

Failed HTTP requests are logged in the console and dispatch litewire:error. Successful requests dispatch litewire:beforeRequest and litewire:afterRequest events around the request.

Loading Indicators

Litewire adds the litewire-request class to the requesting element while a request is in progress, then removes it when the request ends. Put an element with class litewire-indicator inside the requesting element to mark it as an indicator. Alternatively, point lw-indicator to a selector elsewhere on the page.

.litewire-request {
 opacity: 0.6;
 pointer-events: none;
}

.litewire-indicator {
 display: none;
}

.litewire-indicator.litewire-request {
 display: inline;
}

JavaScript Components

Use lw-component to mount a JavaScript ES module on an element. Its path is relative to the application base URL. Litewire imports the module and calls its default export with the element and a plain object made from the element's data-* attributes.

<div lw-component="frontend/components/Counter.js" data-start="3"></div>
<div lw-component="frontend/components/Greeting.js" data-name="Ada"></div>
<div lw-component="frontend/components/TaskList.js"></div>

Counter Component

Greeting Component

Task List Component

Components can be class constructors or functions. Keep module paths publicly accessible to the browser, and use textContent when displaying untrusted values.

Events and Modifiers

Expressions are supported on lw:click, lw:input, lw:change, lw:submit, lw:keydown, lw:keyup, lw:focus, and lw:blur. Expressions can refer to $event, $el, $value, $state, and $wire.

<input lw:keydown.debounce="query = $value">
<button lw:click.prevent="$event.target.textContent = 'Saved'">Submit</button>
<div lw:click.outside="open = false">...</div>

Supported event modifiers include .prevent, .stop, .self, .outside, .once, .window, .document, .capture, .passive, .debounce, and .throttle. Debounce and throttle use a fixed default delay of 250 ms.

Security Notes

Litewire evaluates expressions in directive values as JavaScript. Only put trusted code in these attributes; do not construct expressions by inserting user-provided content. For displaying text, lw:text writes to textContent, but server responses swapped as HTML should still be escaped and validated by the application.

Litewire attaches the CSRF meta-token header to requests when the token exists. Server-side endpoints must still validate CSRF tokens, authorization, and input data.