Livewire 3: Build Dynamic UIs Without JavaScript in Laravel
Learn Livewire 3 to create reactive UIs in Laravel without writing JavaScript.
20+ years shipping production PHP systems at scale. Drawn from code that ran under real load.
- ✓Basic knowledge of PHP and Laravel
- ✓Familiarity with Blade templating
- ✓Laravel 10 or 11 installed
- Livewire 3 allows building dynamic interfaces using PHP and Blade.
- No JavaScript required; reactivity is handled via AJAX.
- Components are PHP classes with public properties and actions.
- Supports real-time validation, file uploads, and polling.
- Works seamlessly with Laravel's ecosystem.
Imagine you have a remote control for your TV that uses radio signals. Normally, you'd need a special cable (JavaScript) to change channels. Livewire is like a magic remote that uses the same radio signals (PHP) to talk to the TV, so you don't need the cable at all.
| Chrome | Firefox | Safari | Edge |
|---|---|---|---|
| ✓ | ✓ | ✓ | ✓ |
Building dynamic, interactive web applications often requires a frontend framework like Vue or React, which means managing state on the client and writing JavaScript. But what if you could achieve the same interactivity using only PHP and Blade templates? That's exactly what Livewire 3 offers. Livewire is a full-stack framework for Laravel that makes building dynamic UIs simple and enjoyable, without leaving the comfort of PHP. In this tutorial, you'll learn how to create reactive components, handle user interactions, and manage state—all with server-side rendering. We'll cover real-world examples like a live search, a counter, and a form with validation. By the end, you'll be able to build modern, dynamic interfaces while leveraging your existing PHP skills. Whether you're building a dashboard, a chat widget, or a complex form, Livewire 3 empowers you to do it faster and with less code.
What is Livewire 3?
Livewire 3 is a full-stack framework for Laravel that allows you to build dynamic, reactive user interfaces using PHP and Blade templates. It eliminates the need for writing JavaScript by handling AJAX requests and DOM diffing automatically. Each Livewire component is a PHP class that extends Livewire\Component and a corresponding Blade view. Public properties in the component are automatically synced with the frontend, and methods can be called from the view using directives like wire:click. Livewire 3 introduces a new JavaScript-less approach, improved performance, and features like #[Rule] attributes for validation, #[Computed] for computed properties, and #[Reactive] for reactive data. It's perfect for developers who want to stay in PHP while building modern interfaces.
Setting Up Livewire 3 in Laravel
To get started with Livewire 3, you need a Laravel application (version 10 or 11 recommended). Install Livewire via Composer: composer require livewire/livewire. Then, publish the configuration file: php artisan livewire:publish --config. Livewire 3 automatically registers its service provider. You can create your first component using the Artisan command: php artisan make:livewire Counter. This generates a PHP class in app/Livewire/Counter.php and a Blade view in resources/views/livewire/counter.blade.php. To render the component in any Blade view, use <livewire:counter /> or @livewire('counter'). Make sure your layout includes Livewire's JavaScript and styles: @livewireStyles in the head and @livewireScripts before the closing body tag. For production, you can compile and cache Livewire's assets using php artisan livewire:publish --assets.
php artisan livewire:publish --assets to serve compiled assets from the public directory.Building a Live Search Component
One of the most common dynamic UI patterns is a live search that filters results as the user types. With Livewire, this is straightforward. Create a component: php artisan make:livewire SearchPosts. In the component class, add a public property $search and a method to query the database. Use the #[Computed] attribute to define a computed property for the results. In the Blade view, bind the input to $search using wire:model.live (which triggers updates on each keystroke). The component will automatically re-render when $search changes. Here's an example that searches posts by title.
wire:model.live (e.g., wire:model.live.debounce.300ms) to reduce server requests.wire:model.live for real-time input binding and #[Computed] for derived data.Form Validation with Livewire 3
Livewire 3 makes form validation a breeze. You can define validation rules using the #[Rule] attribute on properties or in a $rules array. When a user submits the form, Livewire automatically validates the data and displays errors. Use wire:submit.prevent to handle form submission without a page reload. In the Blade view, use @error directives to show validation messages. Livewire also supports real-time validation by adding wire:model.blur or wire:model.live with validation on update. Here's an example of a simple contact form.
#[Rule] attributes for validation and wire:submit.prevent for AJAX form submission.File Uploads in Livewire
Livewire 3 simplifies file uploads with temporary files and progress tracking. Use wire:model on a file input, and Livewire will handle the upload asynchronously. You can validate file types and size using #[Rule]. The uploaded file is stored temporarily and can be moved to permanent storage. Use $this->validate() to ensure the file meets criteria. Livewire also provides a $this->upload() method for more control. Here's an example of a profile picture upload.
php.ini and Livewire config to prevent large uploads.WithFileUploads trait and wire:model on file inputs for easy uploads.Polling and Real-Time Updates
Livewire can poll the server at intervals to update data automatically. Use the wire:poll directive on a container element. For example, to refresh a list of notifications every 10 seconds: <div wire:poll.10s>...</div>. You can also trigger polling on a specific action using $this->dispatch('poll'). In Livewire 3, you can use the #[Reactive] attribute to make a property automatically update when its value changes on the server. This is useful for real-time dashboards. Here's a simple clock component that updates every second.
wire:poll to automatically refresh components at intervals.Security Best Practices
Livewire handles CSRF protection automatically, but you must still follow security best practices. Always validate and sanitize user input. Use $this->validate() or #[Rule] attributes. Be cautious with wire:model on sensitive data; avoid binding to passwords directly. Use wire:model.lazy for password fields to reduce exposure. For authorization, use Laravel's policies and gates within Livewire actions. Never trust $this->all(); always validate. Also, ensure your Livewire components are not exposing sensitive data through public properties. Use #[Computed] for data that should be computed on demand.
The Case of the Missing Livewire Update: A Production Outage
wire:submit.prevent, causing the browser to submit the form traditionally.<button type="submit"> to <button wire:click="update"> and added wire:submit.prevent on the form.- Always use Livewire directives like
wire:clickorwire:submit.preventto intercept actions. - Test interactions in the browser's network tab to ensure AJAX requests are made.
- Avoid mixing native HTML form submissions with Livewire.
- Use
wire:loadingandwire:targetto provide user feedback during requests. - Enable Livewire's debug bar in development to monitor component updates.
wire:click. Replace with Livewire directives.$this->emit() to dispatch events or $this->dispatch() in Livewire 3. Ensure properties are public and included in $rules for validation.wire:model to inputs and use @error directive. Check that the component has $rules property.php artisan livewire:listphp artisan optimize:clear| File | Command / Code | Purpose |
|---|---|---|
| Counter.php | namespace App\Livewire; | What is Livewire 3? |
| counter.blade.php | Setting Up Livewire 3 in Laravel | |
| SearchPosts.php | namespace App\Livewire; | Building a Live Search Component |
| ContactForm.php | namespace App\Livewire; | Form Validation with Livewire 3 |
| UploadPhoto.php | namespace App\Livewire; | File Uploads in Livewire |
| Clock.php | namespace App\Livewire; | Polling and Real-Time Updates |
| SecureComponent.php | namespace App\Livewire; | Security Best Practices |
Key takeaways
wire:model for data binding, wire:click for actions, and wire:submit.prevent for forms.Common mistakes to avoid
3 patternsForgetting to include `@livewireStyles` and `@livewireScripts` in the layout.
Using native HTML form submission instead of `wire:submit.prevent`.
Binding sensitive data like passwords with `wire:model.live`.
Interview Questions on This Topic
What is Livewire and how does it differ from traditional JavaScript frameworks?
Frequently Asked Questions
20+ years shipping production PHP systems at scale. Drawn from code that ran under real load.
That's Laravel. Mark it forged?
3 min read · try the examples if you haven't