How to Create Post Like and unlike Button in Laravel

In this section, we will create like and unlike buttons for posts in Laravel. For this tutorial, we will use Laravel along with the rtconner/laravel-likeable package. For authentication, we will use Laravel Breeze.

Step 1: Create Laravel Project

Installing a fresh new laravel application.

composer create-project --prefer-dist laravel/laravel project-name

Step 2: Set Up Database Details in ENV

Now, you have to connect the laravel app to the database, hence open the .env configuration file and add the database credentials as suggested below.

.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database_name
DB_USERNAME=database_user_name
DB_PASSWORD=database_password

Step 3: Install breeze

You need to install first breeze package.

composer require laravel/breeze --dev

Then, install breeze ui.

php artisan breeze:install

You can install dependencies.

npm install && npm run dev

Step 4 : Create post model and table

php artisan make:model Post -m 

migration file.

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('description');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

app/Models/Post.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'title',
        'description'
    ];
}

Step 5: Install Laravel Likeable Package

composer require rtconner/laravel-likeable

Simple Usage

$post->like(); // like the post for current user
$post->like($myUserId); // pass in your own user id
$post->like(0); // just add likes to the count, and don't track by user

$post->unlike(); // remove like from the post
$post->unlike($myUserId); // pass in your own user id
$post->unlike(0); // remove likes from the count -- does not check for user

$post->likeCount; // get count of likes

$post->likes; // Iterable Illuminate\Database\Eloquent\Collection of existing likes

$post->liked(); // check if currently logged in user liked the post
$post->liked($myUserId);

post::whereLikedBy($myUserId) // find only posts where user liked them
    ->with('likeCounter') // highly suggested to allow eager load
    ->get();

Migrate database

php artisan migrate

Setup your models

<?php

namespace App\Models;

use Conner\Likeable\Likeable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory, Likeable;

    protected $fillable = [
        'title',
        'description'
    ];
}

Create Post Controller

php artisan make:controller PostController

app/Http/Controllers/PostController.php

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{

    public function postList()
    {
        $posts = Post::all();

        return view('posts.post-list',compact('posts'));
    }
    public function likePost($id)
    {
        $post = Post::find($id);
        $post->like();
        $post->save();

        return redirect()->route('post.list')->with('message','Post Like successfully!');
    }

    public function unlikePost($id)
    {
        $post = Post::find($id);
        $post->unlike();
        $post->save();
        
        return redirect()->route('post.list')->with('message','Post Like undo successfully!');
    }
}

Create Routes

<?php

use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::get('/post-list',[PostController::class,'postList'])->name('post.list');
Route::post('/like-post/{id}',[PostController::class,'likePost'])->name('like.post');
Route::post('/unlike-post/{id}',[PostController::class,'unlikePost'])->name('unlike.post');

Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth'])->name('dashboard');

require __DIR__ . '/auth.php';

Step 6 : Create View File

resources/views/post/post-list.blade.php

<x-app-layout>
    <x-slot name="header">
        <h2 class="text-xl font-semibold leading-tight text-gray-800">
            PostList
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="mx-auto max-w-7xl sm:px-6 lg:px-8">
            <div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
                <div class="p-6 bg-white border-b border-gray-200">
                    <div>
                        <h4 class="mb-4 text-2xl font-bold">Post </h4>
                        @if (session()->has('message'))
                        <div class="px-4 py-4 text-green-800 bg-green-200 border-l-4 border-green-900 rounded">
                            {{ session('message') }}
                        </div>
                        @endif
                        <div>
                            <div class="flex flex-col mt-8">
                                <div class="py-2">
                                    <div class="min-w-full border-b border-gray-200 shadow">
                                        <table class="min-w-full">
                                            <thead>
                                                <tr>
                                                    <th
                                                        class="px-6 py-3 text-left text-gray-500 border-b border-gray-200 bg-gray-50">
                                                        #
                                                    </th>
                                                    <th
                                                        class="px-6 py-3 text-left text-gray-500 border-b border-gray-200 bg-gray-50">
                                                        Title
                                                    </th>
                                                    <th
                                                        class="px-6 py-3 text-left text-gray-500 border-b border-gray-200 bg-gray-50">
                                                        Description
                                                    </th>
                                                    <th
                                                        class="px-6 py-3 text-left text-gray-500 border-b border-gray-200 bg-gray-50">
                                                        Action
                                                    </th>
                                                </tr>
                                            </thead>

                                            <tbody class="bg-white">
                                                @foreach($posts as $post)
                                                <tr>
                                                    <td class="px-6 py-4 border-b border-gray-200">
                                                        <div class="flex items-center">
                                                            <div class="ml-4">
                                                                <div class="text-sm text-gray-900">
                                                                    {{ $post->id }}
                                                                </div>
                                                            </div>
                                                        </div>
                                                    </td>

                                                    <td class="px-6 py-4 border-b border-gray-200">
                                                        <div class="text-sm text-gray-900">
                                                            {{ $post->title }}
                                                        </div>
                                                    </td>

                                                    <td class="px-6 py-4 border-b border-gray-200">
                                                        {{ $post->description }}
                                                    </td>

                                                    <td
                                                        class="px-6 py-4 text-sm text-gray-500 border-b border-gray-200 ">
                                                        <form action="{{ route('like.post', $post->id) }}"
                                                            method="post">
                                                            @csrf
                                                            <button
                                                                class="{{ $post->liked() ? 'bg-blue-600' : '' }} px-4 py-2 text-white bg-gray-600">
                                                                like {{ $post->likeCount }}
                                                            </button>
                                                        </form>

                                                    </td>
                                                    <td
                                                        class="px-6 py-4 text-sm text-gray-500 border-b border-gray-200">
                                                        <form action="{{ route('unlike.post', $post->id) }}"
                                                            method="post">
                                                            @csrf
                                                            <button
                                                                class="{{ $post->liked() ? 'block' : 'hidden'  }} px-4 py-2 text-white bg-red-600">
                                                                unlike
                                                            </button>
                                                        </form>
                                                    </td>

                                                </tr>
                                                @endforeach
                                            </tbody>
                                        </table>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</x-app-layout>
unlike and like
saim ansari
saim ansari

I'm Saim Ansari, a full-stack developer with 4+ years of hands-on experience who thrives on building web applications that leave a lasting impression. When it comes to tech, I'm particularly adept at Laravel, React, Tailwind CSS, and the Tall Stack