beubeucode/sillage
Composer 安装命令:
composer require beubeucode/sillage
包简介
First-party, privacy-friendly event tracking for Laravel with native Blade and Inertia support.
README 文档
README
.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, rebuilt for Laravel 11/12.
A Blade app captures full page views automatically from the middleware — zero analytics JavaScript required.
Installation
composer require beubeucode/sillage
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
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
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()
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
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: <key> }
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)
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 & 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 yourapp.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
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
composer test # pest composer analyse # phpstan (max) composer format # pint
License
MIT.
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 2
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-07-02