PHPackages                             tomeet/laravel-footprint - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. tomeet/laravel-footprint

ActiveLibrary[Templating &amp; Views](/categories/templating)

tomeet/laravel-footprint
========================

User footprint (browsing history) feature for Laravel Application.

v1.0.1(1mo ago)01MITPHPPHP ^8.0

Since Jun 15Pushed 1mo agoCompare

[ Source](https://github.com/tomeet/laravel-footprint)[ Packagist](https://packagist.org/packages/tomeet/laravel-footprint)[ RSS](/packages/tomeet-laravel-footprint/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (2)Dependencies (4)Versions (4)Used By (0)

Laravel Footprint
=================

[](#laravel-footprint)

👣 User footprint (browsing history) feature for Laravel Application.

Features
--------

[](#features)

- 🎯 **Passive Tracking** - Automatically record user browsing history via middleware
- 🔄 **Update on Revisit** - Same object revisits update the existing record, keeping the list fresh
- 📸 **Data Snapshot** - Save title, image, and metadata at browse time (survives object deletion)
- 🔒 **Multi-Guard Support** - Works with web session, Sanctum, JWT, and custom guards
- ⚡ **Async Recording** - Supports after-response dispatch or queue jobs
- 🧩 **Polymorphic** - Track any Eloquent model (Product, Post, Article, etc.)

Installation
------------

[](#installation)

```
composer require tomeet/laravel-footprint
```

### Publish Configuration &amp; Migrations

[](#publish-configuration--migrations)

```
php artisan vendor:publish --provider="Tomeet\Laravel\Footprint\FootprintServiceProvider"
```

### Run Migrations

[](#run-migrations)

```
php artisan migrate
```

Configuration
-------------

[](#configuration)

```
// config/footprint.php
return [
    'uuids' => false,
    'user_model' => App\Models\User::class,
    'user_foreign_key' => 'user_id',
    'footprint_table' => 'footprints',
    'footprint_model' => \Tomeet\Laravel\Footprint\Footprint::class,

    // Supported authentication guards
    'guards' => ['web', 'api', 'sanctum'],

    'middleware' => [
        'enabled' => true,
        'auto_attach_web' => false,
        'auto_attach_api' => false,
        'web_route_patterns' => ['products.show', 'posts.show'],
        'api_route_patterns' => ['api.products.show', 'api.posts.show'],
        'except_routes' => ['admin.*', 'api.auth.*'],
        'auth_only' => true,
        'async' => 'afterResponse', // afterResponse | queue | sync
    ],

    'queue' => [
        'enabled' => true,
        'connection' => env('QUEUE_CONNECTION', 'sync'),
        'queue' => 'default',
    ],

    'route_parameters' => [
        'products.show' => 'product',
        'posts.show' => 'post',
        'api.products.show' => 'product',
        'api.posts.show' => 'post',
    ],

    'prune' => [
        'enabled' => true,
        'days' => 30,
    ],
];
```

Setup
-----

[](#setup)

### 1. Add `Footprinter` trait to your User model

[](#1-add-footprinter-trait-to-your-user-model)

```
use Tomeet\Laravel\Footprint\Traits\Footprinter;

class User extends Authenticatable
{
    use Footprinter;
}
```

### 2. Add `Footprintable` trait to models you want to track

[](#2-add-footprintable-trait-to-models-you-want-to-track)

```
use Tomeet\Laravel\Footprint\Traits\Footprintable;

class Product extends Model
{
    use Footprintable;

    // Optional: customize snapshot metadata
    public function getFootprintMeta(): array
    {
        return [
            'price' => $this->price,
            'original_price' => $this->original_price,
            'category_id' => $this->category_id,
        ];
    }
}
```

Usage
-----

[](#usage)

### Automatic Tracking via Middleware (Recommended)

[](#automatic-tracking-via-middleware-recommended)

#### Route-level middleware

[](#route-level-middleware)

```
// routes/web.php
Route::middleware(['auth', 'footprint'])->group(function () {
    Route::get('/products/{product}', [ProductController::class, 'show'])->name('products.show');
});

// routes/api.php
Route::middleware(['auth:sanctum', 'footprint'])->group(function () {
    Route::get('/products/{product}', [ProductController::class, 'show'])->name('api.products.show');
});
```

#### Auto-attach via configuration

[](#auto-attach-via-configuration)

```
// config/footprint.php
'middleware' => [
    'auto_attach_web' => true,
    'auto_attach_api' => true,
    'route_patterns' => ['*.show'],
],
```

### Manual Tracking (when middleware is disabled)

[](#manual-tracking-when-middleware-is-disabled)

```
// config/footprint.php
'middleware' => ['enabled' => false]

// In your controller
public function show(Product $product)
{
    auth()->user()?->recordFootprint($product);
    return response()->json($product);
}
```

API
---

[](#api)

### User (Footprinter)

[](#user-footprinter)

```
$user = User::find(1);

// Record a footprint manually
$user->recordFootprint($product);

// Get paginated footprints
$user->footprintPaginate(20);

// Get recent footprints
$user->recentFootprints(10);

// Get footprint items as a query builder
$user->getFootprintItems(Product::class)->where('status', 'active')->get();

// Check if user has viewed an object
$user->hasFootprinted($product);

// Get specific footprint record
$user->getFootprintOf($product);

// Clear all footprints
$user->clearFootprints();

// Clear footprints by type
$user->clearFootprintsByType(Product::class);

// Attach has_footprinted status to a collection (avoids N+1)
$products = Product::paginate(20);
$user->attachFootprintStatus($products);
```

### Model (Footprintable)

[](#model-footprintable)

```
$product = Product::find(1);

// Get all footprints for this product
$product->footprints;

// Get users who viewed this product
$product->footprinters;

// Count unique viewers
$product->uniqueFootprintersCount();

// Total footprint records
$product->totalFootprintsCount();

// Check if a specific user viewed
$product->hasBeenFootprintedBy($user);

// Get recent viewers
$product->recentFootprinters(10);
```

JSON API Example
----------------

[](#json-api-example)

```
class FootprintController extends Controller
{
    public function index(Request $request)
    {
        $footprints = $request->user()->footprintPaginate(20);

        return response()->json([
            'data' => $footprints->map(fn ($fp) => [
                'id' => $fp->id,
                'title' => $fp->title,
                'image' => $fp->image,
                'meta' => $fp->meta,
                'viewed_at' => $fp->viewed_at->toIso8601String(),
                'viewed_at_human' => $fp->viewed_at->diffForHumans(),
                'is_available' => $fp->footprintable !== null,
                'footprintable' => $fp->footprintable?->only(['id', 'price']),
            ]),
            'meta' => [
                'current_page' => $footprints->currentPage(),
                'last_page' => $footprints->lastPage(),
                'per_page' => $footprints->perPage(),
                'total' => $footprints->total(),
            ],
        ]);
    }
}
```

Pruning Old Records
-------------------

[](#pruning-old-records)

```
// app/Console/Kernel.php
protected function schedule(Schedule $schedule): void
{
    $schedule->command('model:prune', [
        '--model' => [\Tomeet\Laravel\Footprint\Footprint::class],
    ])->daily();
}
```

Or manually:

```
php artisan model:prune --model="Tomeet\Laravel\Footprint\Footprint"
```

Why Middleware Instead of Manual Calls?
---------------------------------------

[](#why-middleware-instead-of-manual-calls)

Favorite (Active)Footprint (Passive)TriggerUser clicks "Favorite" buttonUser visits a pageIntentExplicit actionImplicit behaviorBest PracticeManual call in controllerMiddleware auto-captureRisk of MissingLow (developer chooses)High (easy to forget)Footprint is designed to **not require any code changes in your controllers**.

Related Packages
----------------

[](#related-packages)

- [overtrue/laravel-favorite](https://github.com/overtrue/laravel-favorite) - User favorite feature
- [overtrue/laravel-follow](https://github.com/overtrue/laravel-follow) - User follow feature
- [overtrue/laravel-like](https://github.com/overtrue/laravel-like) - User like feature

License
-------

[](#license)

MIT

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance90

Actively maintained with recent releases

Popularity1

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

45d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/993797eac0ff9310b28dc2fd04cb84a69fb951ed024e7f2ff07b3ecdf7abc233?d=identicon)[tomeet](/maintainers/tomeet)

---

Top Contributors

[![tomeet](https://avatars.githubusercontent.com/u/93234256?v=4)](https://github.com/tomeet "tomeet (5 commits)")

---

Tags

laravelhistoryviewtrackfootprint

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/tomeet-laravel-footprint/health.svg)

```
[![Health](https://phpackages.com/badges/tomeet-laravel-footprint/health.svg)](https://phpackages.com/packages/tomeet-laravel-footprint)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M348](/packages/psalm-plugin-laravel)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9762.4M134](/packages/roots-acorn)[laravel/ai

The official AI SDK for Laravel.

1.0k3.2M251](/packages/laravel-ai)[yajra/laravel-oci8

Oracle DB driver for Laravel via OCI8

8793.2M25](/packages/yajra-laravel-oci8)[pressbooks/pressbooks

Pressbooks is an open source book publishing tool built on a WordPress multisite platform. Pressbooks outputs books in multiple formats, including PDF, EPUB, web, and a variety of XML flavours, using a theming/templating system, driven by CSS.

45444.2k1](/packages/pressbooks-pressbooks)[glushkovds/phpclickhouse-laravel

Adapter of the most popular library https://github.com/smi2/phpClickHouse to Laravel

2051.5M2](/packages/glushkovds-phpclickhouse-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
