pharaonic / laravel-bookmarks
Polymorphic bookmarks for Laravel Eloquent models, with JSON-object metadata and database-enforced uniqueness.
Requires
- php: >=8.3 <8.6
- illuminate/contracts: ^13.0
- illuminate/database: ^13.0
- illuminate/support: ^13.0
Requires (Dev)
- laravel/pint: ^1.20
- orchestra/testbench: ^11.0
- pestphp/pest: ^4.0
- phpstan/phpstan: ^2.1.33
- phpunit/phpunit: ^12.5.8
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-develop
- 13.x-dev
- 13.0.0
- 12.x-dev
- 12.0.0
- 11.x-dev
- 11.0.0
- 10.x-dev
- 10.0.0
- 9.x-dev
- 9.0.0
- 8.x-dev
- 8.0.0
- 7.x-dev
- 7.0.0
- 6.x-dev
- 6.0.0
- dev-fix/shared-code-10.x
- dev-fix/shared-code-11.x
- dev-fix/shared-code-12.x
- dev-fix/shared-code-13.x
- dev-fix/shared-code-7.x
- dev-fix/shared-code-8.x
- dev-fix/shared-code-9.x
- dev-fix/shared-code-6.x
This package is auto-updated.
Last update: 2026-11-13 10:00:23 UTC
README
Polymorphic bookmarks for Eloquent models, with JSON-object metadata.
Installation
composer require pharaonic/laravel-bookmarks php artisan migrate
The service provider is registered automatically, and migrate creates the bookmarks table. Publish the migration only to change it (--tag=bookmarks-migrations), and the configuration only to rename the table, use your own Bookmark model, or turn off cleanup on delete:
php artisan vendor:publish --tag=bookmarks-config
Usage
Add CanBookmark to the model that bookmarks (it does not have to be a user) and HasBookmarks to the model that is bookmarked. A model can use both.
use Illuminate\Foundation\Auth\User as Authenticatable; use Pharaonic\Laravel\Bookmarks\Concerns\CanBookmark; class User extends Authenticatable { use CanBookmark; }
use Illuminate\Database\Eloquent\Model; use Pharaonic\Laravel\Bookmarks\Concerns\HasBookmarks; class Post extends Model { use HasBookmarks; }
$bookmark = $user->bookmark($post, ['note' => 'Read later', 'preferences' => ['notify' => true]]); $bookmark->meta->note; // 'Read later' $bookmark->meta->preferences->notify; // true $bookmark->meta->get('priority', 0); // 0: the key is absent $user->bookmark($post, ['priority' => 2]); // replaces the whole metadata: note is gone $user->bookmark($post); // keeps {"priority":2} $user->bookmark($post, []); // empties it to {} $user->bookmarkOf($post); // the Bookmark, or null $user->hasBookmarked($post); // true $user->unbookmark($post); // true: this call removed it, false when there was none $user->toggleBookmark($post); // the new Bookmark, or null when it was removed Post::whereBookmarkedBy($user)->latest()->paginate(); Post::withBookmarkedBy($user)->withCount('bookmarks')->get(); // each post has is_bookmarked $user->givenBookmarks()->with('bookmarkable')->latest()->get();
Documentation
Full documentation: Laravel Bookmarks Documentation.
Support & Security
See SUPPORT.md and SECURITY.md. Contributions are welcome; see CONTRIBUTING.md.
License
MIT. See LICENSE.
