Architecture
How LiVue works under the hood: data flow, request lifecycle, request pooling, security model, and extensibility.
Data Flow
LiVue implements a server-driven reactivity pattern. The server owns the state and re-renders the Blade template after every action; the client updates the UI through template swapping (dynamic Vue components) instead of DOM morphing. Vue is used purely for client-side interactivity — v-model, v-if, @click — while Blade handles data rendering with standard {{ $var }} syntax.
The Reactivity Cycle
-
1
Server renders Blade template
PHP evaluates the Blade view with the component's state, producing HTML with embedded Vue directives.
-
2
Browser receives HTML with snapshot
The rendered HTML is wrapped in a
<div>withdata-livue-idanddata-livue-snapshotattributes containing the serialized state. -
3
Vue mounts as dynamic component
LiVue's JS runtime finds the wrapper elements, parses the snapshot, and creates a Vue app that renders your template. Child components are registered globally in the same app.
-
4
User interaction triggers AJAX
When the user clicks a button or types into a field, an AJAX request sends the current snapshot and any modified values to the server.
-
5
Server processes the request
The server verifies the integrity of the snapshot, restores the PHP state, executes the requested method, and re-renders the template.
-
6
New HTML + snapshot returned
The response contains the updated snapshot and, if the template changed, new HTML. The JS runtime swaps the Vue component definition and the UI updates instantly.
Template Swapping
Unlike traditional approaches that morph the DOM element by element, LiVue replaces the entire Vue component definition when the server returns updated HTML. Vue destroys the old instance and creates a new one with the fresh template — no diffing algorithms or patch conflicts. This is fast, predictable, and fully compatible with Vue's reactivity system.
Child components work the same way. Each child gets its own independent Vue instance and can be updated independently from the parent.
Request Pooling
All actions that occur in the same JavaScript event loop tick are automatically batched into a single HTTP request. This is especially useful when multiple components on the same page trigger actions simultaneously.
-
1
Actions queued
Each action (direct call,
v-click, orv-modelsync) adds a payload to the pool. -
2
Single request sent
At the end of the microtask, all pending payloads are sent as a single
POST /livue/updatewith the format{ updates: [...] }. -
3
Responses distributed
The server returns
{ responses: [...] }in the same order. Each response is routed to the corresponding component.
Note — Components with #[Isolate] bypass the pool and send their request immediately, independent of other components on the page.
Request Lifecycle
Every LiVue AJAX interaction follows the same lifecycle, whether triggered by a button click, a form submission, or a reactive sync. Here's what happens step by step:
-
1
Request validated
The server checks the request format, verifies the CSRF token, and validates the snapshot structure.
-
2
Checksum verified
The snapshot's integrity checksum (HMAC-SHA256) is verified to ensure the state hasn't been tampered with on the client.
-
3
State restored
The component is instantiated and its state is restored from the snapshot. Complex types (Eloquent models, enums, Carbon dates) are automatically hydrated back to PHP objects. Client-side changes from
v-modelare applied as diffs. -
4
Method executed
The requested public method is invoked after security checks (only methods you define on your class are accessible). If a
ValidationExceptionis thrown, errors are captured automatically. -
5
Template re-rendered
The Blade template is rendered with the updated state. If the output differs from before the method call, the new HTML is included in the response.
-
6
Response returned
The new snapshot plus any HTML changes are sent back. The client swaps the template and updates the Vue state. Errors in one component don't block others in the same batch.
The response may also include:
- -
redirect— If$this->redirect()was called (short-circuits the response). - -
events— If the component dispatched events to other components. - -
js— If the component called$this->vue($js)to execute JavaScript client-side. - -
errors— If there are validation errors.
Security Model
LiVue implements multiple layers of security to protect server state, prevent unauthorized method calls, and ensure request integrity.
State Integrity (HMAC-SHA256)
Every snapshot includes a checksum signed with your application key. The client cannot tamper with the state without invalidating the signature. Any mismatch returns a 403 error.
Method Protection
Only public methods you define on your own component class are callable from the client. Magic methods, lifecycle hooks (boot, mount, etc.), non-public methods, and base class methods are all blocked automatically.
Guarded Properties
Properties marked with #[Guarded] are completely hidden from the browser. They're encrypted and stored separately — the client never sees or modifies them. See the Attributes page for details.
CSRF Protection
Standard Laravel web middleware handles CSRF. The JS runtime reads the token from <meta name="csrf-token"> and sends it automatically with every request.
Persistent Middleware
Route middleware (auth, can, verified, etc.) from the initial page load are automatically re-applied on every AJAX request. If a user's permissions change, subsequent requests will be rejected.
Authorization
Components include Laravel's AuthorizesRequests trait, so you can use $this->authorize() with Gates and Policies directly in your component methods.
Request Validation
Every AJAX request is validated before processing: JSON format, snapshot structure, component name format (prevents path traversal), and method name checks. One invalid item rejects the entire batch.
CSP Support
LiVue supports strict Content Security Policy via nonce-based script loading. Enable csp_nonce in config and use the LiVueCspMiddleware.