modularavel/favoritable

A Laravel Livewire package to add favorites functionality to your application

Installs: 0

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/modularavel/favoritable

v1.0.0 2025-10-09 18:15 UTC

This package is auto-updated.

Last update: 2025-10-09 20:22:21 UTC


README

A Laravel Livewire package that adds favorites functionality to your Laravel 11+ application. Allow users to favorite any model in your application with a beautiful, customizable UI.

Features

  • Add favorites to any Eloquent model
  • Beautiful Livewire components with multiple variants
  • Favorite button with counter
  • Favorites list page
  • Tailwind CSS styling included
  • Full test coverage with Pest
  • Easy to customize
  • Real-time updates

Requirements

  • PHP 8.2+
  • Laravel 11.0+ or Laravel 12.0+
  • Livewire 3.0+
  • Tailwind CSS

Installation

Install the package via Composer:

composer require modularavel/favoritable

Publish the migrations:

php artisan vendor:publish --tag="modularavel:favoritable-migrations"

Run the migrations:

php artisan migrate

Optionally, publish the config file:

php artisan vendor:publish --tag="modularavel:favoritable-config"

Optionally, publish the views for customization:

php artisan vendor:publish --tag="modularavel:favoritable-views"

Setup

1. Add the Trait to Your Model

Add the Favoritable trait to any model you want users to be able to favorite:

use Modularavel\Favoritable\Traits\HasModularavelFavoritable;

class Post extends Model
{
    use HasModularavelFavoritable;
}

2. Import CSS Styles

Add the package CSS to your main CSS file or import it in your layout:

@import '../../vendor/modularavel/favoritable/resources/css/favoritable.css';

Or include it directly in your Tailwind config:

module.exports = {
  content: [
    './vendor/modularavel/favoritable/resources/**/*.blade.php',
  ],
}

Usage

Favorite Button Component

The simplest way to add a favorite button:

<livewire:favoritable-btn :model="$post" />

Button Variants

Choose from multiple button styles:

{{-- Default variant --}}
<livewire:favoritable-btn :model="$post" variant="default" />

{{-- Outline variant --}}
<livewire:favoritable-btn :model="$post" variant="outline" />

{{-- Solid variant --}}
<livewire:favoritable-btn :model="$post" variant="solid" />

{{-- Icon only variant --}}
<livewire:favoritable-btn :model="$post" variant="icon" />

Button Sizes

Choose from three sizes:

{{-- Small --}}
<livewire:favoritable-btn :model="$post" size="sm" />

{{-- Medium (default) --}}
<livewire:favoritable-btn :model="$post" size="md" />

{{-- Large --}}
<livewire:favoritable-btn :model="$post" size="lg" />

Hide Counter

You can hide the favorites counter:

<livewire:favoritable-btn :model="$post" :show-count="false" />

Favorites List Component

Display a paginated list of user's favorites:

<livewire:favoritable-list />

Filter by Type

Show only favorites of a specific type:

<livewire:favoritable-list type="Post::class" />

Custom Pagination

<livewire:favoritable-list :per-page="20" />

Model Methods

The Favoritable trait adds several helpful methods to your models:

// Check if favorited by a user
$post->isFavoritedBy($user);

// Toggle favorite
$post->toggleFavorite($user);

// Add favorite
$post->addFavorite($user);

// Remove favorite
$post->removeFavorite($user);

// Get favorites count
$post->favoritesCount();

// Query scope for favorited items
Post::favoritedBy($user)->get();

Customizing the Favorites List Display

To customize how your favorited items appear in the favorites list, implement these methods in your model:

class Post extends Model
{
    use Favoritable;

    public function getFavoritableTitle(): string
    {
        return $this->title;
    }

    public function getFavoritableDescription(): ?string
    {
        return $this->excerpt;
    }

    public function getFavoritableImage(): ?string
    {
        return $this->featured_image;
    }

    public function getFavoritableUrl(): string
    {
        return route('posts.show', $this);
    }
}

Configuration

The package includes a configuration file with sensible defaults:

return [
    // The fully qualified class name of the user model
    'user_model' => env('FAVORITABLE_USER_MODEL', 'App\\Models\\User'),

    // The name of the belongTo relationship on the favoritable model to the user model
    'owner_relationship_name' => env('FAVORITABLE_OWNER_RELATIONSHIP_NAME', 'user'),

    // Button configuration
    'button' => [
        'default_variant' => 'default',
        'default_size' => 'md',
        'show_count' => true,
    ],

    // List configuration
    'list' => [
        'per_page' => 12,
    ],
];

Events

The package dispatches Livewire events that you can listen to:

favoriteToggled

Dispatched when a favorite is toggled:

Livewire.on('favoriteToggled', (data) => {
    console.log(data.modelType);
    console.log(data.modelId);
    console.log(data.isFavorited);
});

Testing

The package includes comprehensive Pest tests. To run tests:

composer test

Styling

The package uses Tailwind CSS for styling. All styles are scoped to avoid conflicts with your application. You can customize the appearance by:

  1. Publishing the views and modifying the Blade templates
  2. Overriding the CSS classes in your application's CSS
  3. Modifying the published CSS file

Advanced Usage

Custom Favorite Model

If you need to extend the Favorite model:

use Modularavel\Favoritable\Models\Favorite as BaseFavorite;

class Favorite extends BaseFavorite
{
    // Your custom code
}

Middleware Protection

Protect your favorites routes with middleware:

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

License

MIT

Credits

  • Modularavel
  • All Contributors

Support

For issues, questions, or contributions, please visit the GitHub repository.