NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
Likes for Laravel

Feed hydration (no N+1)

Render per-row viewer state for an entire feed page in a single query instead of one exists() per row. withLikedState() adds two attributes to each model:

$posts = Post::query()
    ->withLikedState()      // adds is_liked + liked_reaction for the current viewer
    ->withLikesCount()      // composes — still one query
    ->latest()
    ->paginate();
@foreach ($posts as $post)
    {{ $post->is_liked ? '♥' : '♡' }} {{ $post->likes_count }}
@endforeach
  • is_liked is a 0/1 flag; liked_reaction is the viewer’s reaction type or null. When the viewer left several reactions, liked_reaction is the one listed first in config('likes.reactions').
  • The actor defaults to the resolved auth actor (actor_resolver, else auth()->user()).
  • For guests — no resolvable actor — it renders is_liked = 0 and liked_reaction = null without throwing, so guest feeds still work.

Explicit actor & reaction

Pass an actor explicitly, and narrow to one reaction type:

Post::withLikedState($user)->get();           // an explicit actor
Post::withLikedState($user, 'love')->get();   // only the viewer's "love" counts as liked

Both attributes come from correlated subqueries on the likes table, so the scope composes with withLikesCount(), eager loads, pagination and your own select() calls.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.