Getting Started with Laravel 12 and Livewire: A Complete Beginner's Guide

Author

Kritim Yantra

May 12, 2025

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.

Tags

Comments

No comments yet. Be the first to comment!

Please log in to post a comment:

Sign in with Google

Related Posts