PHPackages                             beubeucode/sillage - 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. beubeucode/sillage

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

beubeucode/sillage
==================

First-party, privacy-friendly event tracking for Laravel with native Blade and Inertia support.

0.1.0(1mo ago)01MITPHPPHP ^8.2CI passing

Since Jul 2Pushed 1mo agoCompare

[ Source](https://github.com/BeubeuCode/sillage)[ Packagist](https://packagist.org/packages/beubeucode/sillage)[ Docs](https://github.com/beubeucode/sillage)[ RSS](/packages/beubeucode-sillage/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (8)Versions (2)Used By (0)

Sillage
=======

[](#sillage)

```
   .oooooo..o ooooo ooooo        ooooo              .o.        .oooooo.    oooooooooooo     /\_/\
  d8P'    `Y8 `888' `888'        `888'             .888.      d8P'  `Y8b   `888'     `8    ( X o )
  Y88bo.       888   888          888             .8"888.    888           888
   `"Y8888o.   888   888          888            .8' `888.   888           888oooo8        \  ~  /
       `"Y88b  888   888          888           .88ooo8888.  888     ooooo 888    "         `---'
  oo     .d8P  888   888       o  888       o  .8'     `888. `88.    .88'  888       o
  8""88888P'  o888o o888ooooood8 o888ooooood8 o88o     o8888o `Y8bood8P'  o888ooooood8

```

First-party, privacy-friendly event tracking for Laravel. Two tables (`visits` + `events`), cookie-based tokens, IP masking on write, and native adapters for both Blade and Inertia (React). Inspired by [Ahoy](https://github.com/ankane/ahoy), rebuilt for Laravel 11/12.

A Blade app captures full page views automatically from the middleware — zero analytics JavaScript required.

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

[](#installation)

```
composer require beubeucode/sillage
```

### Quick install

[](#quick-install)

```
php artisan sillage:install
```

Publishes the config and migrations, then interactively configures IP masking and offers to run the migrations. Non-interactive flags for CI:

```
php artisan sillage:install --mask-strategy=hash   # truncate | hash
php artisan sillage:install --no-mask              # store raw IPs
php artisan sillage:install --force                # overwrite published files
```

The masking choice is written to `.env` as `SILLAGE_MASK_IPS` and `SILLAGE_IP_MASK_STRATEGY` (if no `.env`exists, the command prints the values to set manually).

### Manual install

[](#manual-install)

```
php artisan vendor:publish --tag=sillage-migrations
php artisan vendor:publish --tag=sillage-config
php artisan migrate
```

The `TrackVisit` middleware is appended to the `web` group automatically. Every full page load (Blade or an Inertia hard load) records a visit and a `$view` event; Inertia partial reloads are ignored.

Tracking events
---------------

[](#tracking-events)

Facade:

```
use Beubeucode\Sillage\Facades\Sillage;

Sillage::track('create-dispute', ['dispute_id' => 42]);
```

Global helper (prefixed to avoid collisions in a public package):

```
sillage_track('create-dispute', ['dispute_id' => 42]);
```

Event names are normalized to `snake_case`, so `Create Dispute`, `createDispute` and `create-dispute` all land as `create_dispute`. When `sillage.enabled` is `false`, `track()` is a silent no-op that returns an unpersisted `Event` — handy for local and test environments.

### Aliasing to a bare `track()`

[](#aliasing-to-a-bare-track)

If you want a shorter `track()` in your own app you can alias it yourself:

```
if (! function_exists('track')) {
    function track(string $name, array $properties = []): \Beubeucode\Sillage\Models\Event {
        return sillage_track($name, $properties);
    }
}
```

This is intentionally **not** shipped by default: a bare `track()` in a public package is a collision waiting to happen. Add it at your own risk.

### Trackable models

[](#trackable-models)

Add the trait to any Eloquent model to auto-inject its key:

```
use Beubeucode\Sillage\Concerns\Trackable;

class Dispute extends Model
{
    use Trackable;
}

$dispute->track('create-dispute'); // properties: { dispute_id:  }
```

Blade
-----

[](#blade)

Publish the script view and drop the directive in your layout:

```
php artisan vendor:publish --tag=sillage-views
```

```
@sillage
```

It renders a tiny `window.sillage()` client:

```
sillage('create-dispute', { dispute_id: 42 });
```

The directive can be disabled with `sillage.blade_directive`.

Inertia (React)
---------------

[](#inertia-react)

Publish the hook:

```
php artisan vendor:publish --tag=sillage-js
```

```
import { useSillage } from '@/vendor/sillage/useSillage';

const { track } = useSillage();
track('create-dispute', { dispute_id: 42 });
```

It posts with `fetch` (never `router.post`, so no Inertia visit and no history pollution), reads CSRF from the `XSRF-TOKEN` cookie, and uses `keepalive: true`. Both adapters hit the same `POST /sillage/events` endpoint.

Privacy &amp; GDPR
------------------

[](#privacy--gdpr)

**IP masking** is on by default (`sillage.mask_ips`). Raw IPs are never stored. Two strategies:

- `truncate` (default) — zeroes the last IPv4 octet / final IPv6 block.
- `hash` — SHA-256 of the IP, keyed with your `app.key`.

**Anonymization** for data retention / crypto-shredding flows:

```
php artisan sillage:anonymize            # nulls old records past sillage.anonymize.retention_days
php artisan sillage:anonymize --user=42  # anonymize a single user regardless of age
```

It nulls `ip`, `user_agent` and `user_id` on matching visits and `user_id` on matching events.

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

[](#configuration)

All behavior is externalized in `config/sillage.php`: `enabled`, `tables`, `visit_duration`, `visitor_duration`, `cookies`, `mask_ips`, `ip_mask_strategy`, `user_model`, `blade_directive`, and `routes` (`enabled`, `prefix`, `middleware`). The events endpoint is throttled (`throttle:60,1`) and can be disabled entirely with `sillage.routes.enabled`.

Testing
-------

[](#testing)

```
composer test      # pest
composer analyse   # phpstan (max)
composer format    # pint
```

License
-------

[](#license)

MIT.

###  Health Score

35

—

LowBetter than 77% of packages

Maintenance90

Actively maintained with recent releases

Popularity1

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

 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

Unknown

Total

1

Last Release

48d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/9b283da269ce50df584af49e2e620aacc5fd85a430adaca07cfb1ce1520138b4?d=identicon)[BeubeuCode](/maintainers/BeubeuCode)

---

Top Contributors

[![BeubeuCode](https://avatars.githubusercontent.com/u/30768799?v=4)](https://github.com/BeubeuCode "BeubeuCode (33 commits)")

---

Tags

ahoybladeevent-trackingeventsinertiajslaravelphpphp8postgresqlreacttrackingtypescriptlaraveltrackinginertiaanalyticsprivacyAhoy

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/beubeucode-sillage/health.svg)

```
[![Health](https://phpackages.com/badges/beubeucode-sillage/health.svg)](https://phpackages.com/packages/beubeucode-sillage)
```

###  Alternatives

[moonshine/moonshine

Laravel administration panel

1.3k268.2k89](/packages/moonshine-moonshine)[psalm/plugin-laravel

Psalm plugin for Laravel

3345.4M354](/packages/psalm-plugin-laravel)[laravel/horizon

Dashboard and code-driven configuration for Laravel queues.

4.2k99.8M355](/packages/laravel-horizon)[illuminate/database

The Illuminate Database package.

2.8k55.8M13.1k](/packages/illuminate-database)[laravel/ai

The official AI SDK for Laravel.

1.1k4.6M327](/packages/laravel-ai)[tallstackui/tallstackui

TallStackUI is a powerful suite of Blade components that elevate your workflow of Livewire applications.

731189.9k16](/packages/tallstackui-tallstackui)

PHPackages © 2026

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