Getting Started with Laravel 12 and Livewire: A Complete Beginner's Guide
Laravel 12, released in early 2025, continues to push the boundaries of elegant web development. One of its most exciting features is the seamless integration with Livewire, a powerful package that lets you build interactive interfaces using just PHP and Blade—no JavaScript required.
This blog is your step-by-step guide to building your first Livewire application using Laravel 12. We'll cover everything from installation and configuration to creating components, handling forms, real-time validation, CRUD operations, file uploads, and even pagination.
Prerequisites
Before diving in, make sure your development environment is ready:
- PHP 8.2 or higher
- Composer
- Node.js & NPM or Bun (for compiling frontend assets)
- A database like MySQL, PostgreSQL, or SQLite
Step 1: Create a New Laravel 12 Project
Start by creating a fresh Laravel project:
composer global require laravel/installer
laravel new laravel12-livewire-tutorial
cd laravel12-livewire-tutorial
Set your database credentials in the .env file and run:
php artisan key:generate
Step 2: Install Livewire
Add Livewire to your project with Composer:
composer require livewire/livewire
Then publish its config and asset files (optional):
php artisan livewire:publish --assets
php artisan vendor:publish --tag=livewire:config
Update your layout (usually resources/views/layouts/app.blade.php) to include Livewire styles and scripts:
<!-- Inside <head> -->
@livewireStyles
<!-- Before </body> -->
@livewireScripts
Step 3: Use the Livewire Starter Kit (Optional)
Laravel 12 offers a Livewire UI starter kit:
php artisan ui livewire
npm install && npm run dev
php artisan migrate
This scaffolds basic auth and dashboard views for rapid prototyping.
Step 4: Create Your First Livewire Component
Generate a simple counter component:
php artisan make:livewire Counter
Edit app/Http/Livewire/Counter.php:
namespace App\Http\Livewire;
use Livewire\Component;
class Counter extends Component
{
public $count = 0;
public function increment()
{
$this->count++;
}
public function render()
{
return view('livewire.counter');
}
}
Edit the view resources/views/livewire/counter.blade.php:
<div style="text-align: center;">
<button wire:click="increment">+</button>
<h1>{{ $count }}</h1>
</div>
Display it in your page:
@livewire('counter')
Step 5: Add Real-Time Validation
Update Counter.php with validation logic:
public $name = '';
protected $rules = [
'name' => 'required|min:3',
];
public function updated($propertyName)
{
$this->validateOnly($propertyName);
}
And update the view:
<input type="text" wire:model="name">
@error('name') <span class="error">{{ $message }}</span> @enderror
Step 6: Build a Simple CRUD Application
Create a Model and Migration
php artisan make:model Task -m
Update migration:
Schema::create('tasks', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description')->nullable();
$table->timestamps();
});
Run migration:
php artisan migrate
Create Livewire Component
php artisan make:livewire Tasks
Logic for Tasks.php
public $tasks, $title, $description, $task_id;
public $updateMode = false;
public function render()
{
$this->tasks = Task::all();
return view('livewire.tasks');
}
private function resetInputFields()
{
$this->title = '';
$this->description = '';
}
public function store()
{
$validated = $this->validate([
'title' => 'required|min:3',
'description' => 'nullable',
]);
Task::create($validated);
session()->flash('message', 'Task Created Successfully.');
$this->resetInputFields();
}
public function edit($id)
{
$task = Task::findOrFail($id);
$this->task_id = $id;
$this->title = $task->title;
$this->description = $task->description;
$this->updateMode = true;
}
public function update()
{
$validated = $this->validate([
'title' => 'required|min:3',
'description' => 'nullable',
]);
$task = Task::find($this->task_id);
$task->update($validated);
$this->updateMode = false;
session()->flash('message', 'Task Updated Successfully.');
$this->resetInputFields();
}
public function delete($id)
{
Task::find($id)->delete();
session()->flash('message', 'Task Deleted Successfully.');
}
View for tasks.blade.php
Add form inputs, buttons, and a list of tasks with wire:model, wire:click, and conditional rendering.
Step 7: Upload Files with Livewire
Use the WithFileUploads trait:
use Livewire\WithFileUploads;
class Tasks extends Component
{
use WithFileUploads;
public $photo;
// ...
}
Handle file uploads:
$this->validate([
'photo' => 'image|max:1024',
]);
$path = $this->photo->store('photos', 'public');
Update Blade:
<input type="file" wire:model="photo">
@error('photo') <span class="error">{{ $message }}</span> @enderror
Step 8: Add Pagination
Use the WithPagination trait:
use Livewire\WithPagination;
class Tasks extends Component
{
use WithPagination;
protected $paginationTheme = 'tailwind';
}
Render paginated tasks:
public function render()
{
return view('livewire.tasks', [
'tasks' => Task::paginate(10),
]);
}
In Blade:
{{ $tasks->links() }}
Step 9: Prepare for Deployment
Compile assets:
npm run production
Set file permissions:
chmod -R 775 storage bootstrap/cache
Optimize:
php artisan config:cache
php artisan route:cache
php artisan view:cache
Conclusion
You’ve just built a dynamic web application using Laravel 12 and Livewire! This stack allows you to develop reactive interfaces using only PHP and Blade, avoiding the complexity of JavaScript-heavy frameworks. From simple counters to full CRUD with validation, file uploads, and pagination, you're now equipped to create production-ready apps.
Projects to explore next
Source-code projects from the KritiMyantra catalogue. Check each project's details before buying.
Flask Authentication System (Free Version) - Kritim Yantra
🛠 Features✔ Google & GitHub Authentication✔ User Registration & Login✔ Profile/Dashboard Access✔ Secure & Mi...
Flask Blog CMS with Admin Dashboard — Python Source Code
A Flask-based blogging website with a built-in admin dashboard. Manage articles, images, categories, tags and featured p...
Laravel 12 + ReactJS Starter Kit: Add Multi-Language Support (Arabic, English, Spanish) with Blog CRUD
🚀 Installation & Setup Download & Extract Get the ZIP from kritimyantra.com and extract it. Includes preconfigu...
Comments
No comments yet. Be the first to comment.
Sign in to join the discussion.