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

Laravel Visits Laravel Package

awssat/laravel-visits

Laravel Visits lets you track and count visits to Eloquent models, pages, or any item with a simple, cache-friendly API. It supports unique visits, IP and user-agent filtering, custom events, and fast stats for dashboards and analytics.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and publish the config plus the migrations (needed for the Eloquent driver):

composer require awssat/laravel-visits
php artisan vendor:publish --provider="Awssat\Visits\VisitsServiceProvider"
php artisan migrate

Open config/visits.php first — it is the only thing you normally need to touch. The two decisions that matter are:

  • driver — eloquent (durable, SQL-backed, one row per visit) or redis (fast counters, ideal for high write volume). Redis requires a working redis connection in config/database.php plus predis/phpredis.
  • ip_protection / ip_protection_time — whether the package should suppress repeat visits from the same IP within a window.

Attach the trait to any model you want to count:

use Awssat\Visits\Traits\Visitable;

class Post extends Model
{
    use Visitable;
}

First use case — a page-view counter in a controller:

public function show(Post $post)
{
    $post->visits()->increment();

    return view('posts.show', [
        'post' => $post,
        'views' => $post->visits()->count(),
    ]);
}

If you don't want the trait, instantiate directly: (new \Awssat\Visits\Visits($post))->increment().

Implementation Patterns

Separate counters with tags. Tags let one model carry multiple independent metrics without extra columns:

$post->visits()->increment();                 // views
$post->visits()->tag('like')->increment();    // likes
$post->visits()->tag('share')->increment();   // shares

$post->visits()->tag('like')->count();

Keep tag strings in constants or an enum — a typo silently creates a new counter.

Time-windowed / trending queries. Period counts are built in:

$post->visits()->visits('day');
$post->visits()->visits('week');
$post->visits()->visits('month');
$post->visits()->visits('year');

Use these for "trending this week" widgets rather than querying the raw visits table yourself.

Leaderboards. Use the package's top-query rather than orderBy on a denormalized column:

$top = \Awssat\Visits\Visits::make(Post::class)->top(10);

Explicit IP identity. When you want control beyond the global ip_protection setting (e.g. only dedupe logged-in users), chain the IP yourself:

$post->visits()->IP(request()->ip()) ?? $post->visits()->increment();

Check isVisited() (or equivalent) when you need to display "already viewed" without incrementing.

Weighted visits. increment($n) lets you record engagement rather than raw loads — useful for read-time or scroll-depth scores:

$post->visits()->increment($minutesRead);

Decouple writes from the request. For high-traffic endpoints, push the increment onto a queue so a slow Redis/SQL write never blocks the response:

dispatch(new RecordVisit($post))->onQueue('metrics');

Wrap tracking in middleware when the rule is uniform ("every GET on /posts/* counts"). Keep the controller clean and skip it for bots/prefetch via a user-agent check before dispatching.

Prefer Redis in production, Eloquent for small apps / local. Eloquent gives you auditability and easy SQL reporting; Redis gives you INCR speed but needs a persistence story.

Gotchas and Tips

  • Eloquent writes a row per visit. On a busy site the visits table grows quickly. Plan a prune job or move to Redis before the table becomes a reporting burden.
  • IP protection will make your local testing look broken. The second increment() from 127.0.0.1 silently does nothing. Disable ip_protection in local/testing, or vary the IP in tests.
  • Identity is tied to the model class name (and morph alias if you use morphMap). Renaming a model or changing its morph alias orphans existing counts — migrate the stored identifiers in the same deploy.
  • Cached counts are stale by design. With cache enabled, count() can lag by the configured timeout. Disable the cache (or flush it) after bulk imports, resets, or admin-side corrections.
  • Driver changes are not a data migration. Switching eloquent → redis (or back) starts from zero; there is no automatic import. Decide the driver before launch, or write your own backfill.
  • Deleting a model does not delete its visits. Add a deleting hook or a scheduled cleanup for orphaned rows/keys.
  • Chain state is per-call. $post->visits()->tag('like') and $post->visits()->count() are separate instances — don't assume a tag set on one call carries to the next.
  • Redis isolation matters. Give the package its own connection/prefix in config/visits.php so a FLUSHDB or cache clear elsewhere doesn't wipe your counters, and keep the prefix identical across every app server.
  • Testing: RefreshDatabase clears SQL but not Redis. Point tests at a dedicated Redis database and flush it in setUp, or you'll get order-dependent failures.
  • No auth or rate limiting is built in. Wrap the increment route with throttle middleware, otherwise a refresh loop inflates counts (and IP protection only helps within its time window).
  • Period queries can't be backfilled. They are derived from timestamps at write time; if you start tracking late, historical "visits this month" is simply zero — don't expect to reconstruct it.
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.
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log