Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message
Eloquent Viewable

Eloquent Viewable Laravel Package

cyrildewit/eloquent-viewable

Eloquent Viewable is a minimalistic analytics package for Laravel that adds seamless view tracking to Eloquent models, with cooldowns, queued recording, unique counts, and period-based queries.

View on GitHub
Deep Wiki
Context7

A minimalistic analytics package for Laravel with seamless view tracking for Eloquent models

Frequently asked questions about Eloquent Viewable
How do I install and set up eloquent-viewable in a Laravel app?
Install the package with Composer using composer require cyrildewit/eloquent-viewable, then publish the package migrations with php artisan vendor:publish and run php artisan migrate. To enable tracking on a model, add the InteractsWithViews trait and implement the Viewable contract. After that you can call views($model)->record() from a controller or service. Setup is additive and does not modify your existing tables beyond creating the views table.
Which Laravel and PHP versions does eloquent-viewable support?
The package requires Laravel 6 or higher and PHP 7.4 or higher, and the current 7.x line claims compatibility through Laravel 13. Lumen is not supported. Because a README compatibility claim is not the same as a tested matrix, pin the exact framework minor you run and verify it in your upgrade runbook. Laravel 6 through 13 covers a wide window, so most maintained applications will fit.
How do I record a view for an Eloquent model with eloquent-viewable?
Add the InteractsWithViews trait and Viewable contract to the model, then call views($post)->record() in the place where a view should count, typically a controller show action. Each call inserts a row into the views table keyed by viewable_id and viewable_type, with optional visitor, collection, and cooldown metadata. Because the record is a write on the request path, keep it on your hottest route in mind when planning load. You can also queue the recording if you do not want the insert inside the request cycle.
How does the view cooldown work in eloquent-viewable?
You attach a cooldown before recording, for example views($post)->cooldown(60)->record(), so repeat views within the window are not stored again. The cooldown relies on session or cookie state, meaning it is per-browser rather than per-authenticated-user. It is the simplest way to stop a single reader from inflating counts on refresh. Treat cooldown windows as product decisions, since long windows hide genuine repeat engagement.
What is the difference between total views and unique views in eloquent-viewable?
Total views counts every recorded row in the views table, while unique views counts distinct visitors within the scope you query. Unique views are based on a cookie-held visitor identifier rather than a logged-in user, so they are approximate and are affected by incognito mode, Do Not Track, cleared cookies, and crawler filtering. Storing a visitor identifier also has GDPR and ePrivacy implications, so confirm with legal before enabling unique counts in the EU. For most content pages total views is the more reliable headline number.
Can I queue view recording so it does not slow down requests?
Yes, the package supports queueing view recording, which moves the INSERT out of the request cycle. This matters on high-traffic show routes where the insert, crawler detection, and session checks add latency and lock contention. Queueing does not reduce the number of rows written, so you still need a retention or partitioning plan for the views table. Make sure your queue workers are reliable, otherwise analytics will silently drift.
How do I order models by view count or popularity in Laravel?
Eloquent Viewable ships query scopes such as orderByViews and orderByUniqueViews, including period and collection variants. That lets you build most-popular listings without hand-written SQL. These scopes run live aggregate queries against the views table, which is fine for modest volumes but can be expensive on large tables. For high-traffic surfaces consider a denormalized counter column updated asynchronously instead.
Why are my views not being recorded when testing with Postman or feature tests?
Crawler detection is enabled by default, and Postman is treated as a crawler, so its requests are filtered out and no view row is written. The same happens with many automated test clients, which produces misleading test results and support tickets that analytics is broken. Disable or fake the crawler detector in your test environment, or assert against a request that passes the detector. Check the package configuration for the crawler detection toggle before debugging your controller.
Will the views table grow too large, and how should I handle retention?
Yes. The package stores one row per view by default, and its own documentation warns the table can grow rapidly. At high traffic volumes this becomes a partitioning and retention problem within months, and no pruning, archival, or aggregation command ships with the package. Plan a retention window, a scheduled cleanup job, and possibly a rollup table for long-term counts. Someone on the team must explicitly own the views table lifecycle, including backups and growth alerts.
Can I customize the View model or add columns like tenant_id or referrer?
Yes, the package documents extensibility points including custom Views, View, and Visitor models, a custom crawler detector, and macros. You can extend the default View model and publish a modified migration to add columns such as tenant_id, referrer, or device type. If you need to count or filter by those columns at scale, also review the indexes, since the default migration indexes viewable_id and viewable_type but not visitor. This is the right path when you need analytics dimensions beyond a plain count.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
adachsoft/command-executor-lib
tagixo/document-builder
tagixo/page-builder
tagixo/mail-builder
tagixo/form-builder
primix/primix
tagixo/core
alesima/laravel-azure-service-bus
tomshaw/shopcart
likyly/laravel
darthsoup/shoppingcart
tdt/core
labyrinthe/connect-php
encore2/laravel-admin2
cboxdk/laravel-console-kit
shapecode/doctrine-dbal-datetimeutc
gilads-otiannoh254/inertia-protocol
dakiquang/laravel-oauth-refresh-lock
woda/laravel-worktrees
dalefranks/ramasite