---
title: "Model events (Trackable) — Plausible for Laravel | Roundly"
description: "Emit Plausible events on Eloquent lifecycle hooks with the Trackable trait — custom props, URL and site per model."
url: https://roundly-consulting.com/open-source/docs/plausible-for-laravel/model-events
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Plausible for Laravel](https://roundly-consulting.com/open-source/docs/plausible-for-laravel.md)

# Model events (Trackable)

Add the Trackable trait to emit Plausible events on Eloquent lifecycle hooks. Map a hook to an event name with $plausibleEvents, and optionally build per-model props:

```php
use Illuminate\Database\Eloquent\Model;
use RoundlyConsulting\Plausible\Concerns\Trackable;

class Order extends Model
{
    use Trackable;

    /** @var array<string, string> */
    protected array $plausibleEvents = [
        'created' => 'Order Placed',
        'updated' => 'Order Updated',
        'deleted' => 'Order Cancelled',
    ];

    /** @return array<string, mixed> */
    protected function plausibleEventProps(string $event): array
    {
        return ['total' => $this->total, 'plan' => $this->plan];
    }
}
```

Any Eloquent model event works as a key — created, updated, deleted and so on. The map is read from the property’s default value when the model boots.

## Customising the payload

Override these protected methods; the first two receive the Plausible event name (for example Order Placed):

- plausibleEventProps(string $event) — custom props sent with the event (none by default).
- plausibleEventUrl(string $event) — the URL attributed to the event; defaults to the app URL plus the model’s table and key.
- plausibleEventSite() — the site the event goes to; defaults to config('plausible.site'), and null skips the event.

```php
// The URL attributed to the event — defaults to {app.url}/{table}/{key}
protected function plausibleEventUrl(string $event): string
{
    return route('orders.show', $this);
}

// The site the event goes to — defaults to config('plausible.site'); null skips the event
protected function plausibleEventSite(): ?string
{
    return $this->tenant->analytics_domain;
}
```

## Firing an event manually

```php
// Same site, visitor and queue rules as the lifecycle hooks — any event name
$order->dispatchPlausibleEvent('Order Refunded');
```

## Transactions

Each event waits for the database change to be saved for good: inside a transaction it is sent (or queued) once the transaction commits, and never if it rolls back. Outside a transaction it goes out at once:

```php
use Illuminate\Support\Facades\DB;

DB::transaction(function () {
    Order::create(['total' => 99]);   // 'Order Placed' is sent (or queued) once the transaction commits
});                                   // a rolled-back save is never tracked
```

## Visitor, site and queue

The visitor comes from the current request when there is one. In the console or on a queue worker — where Laravel binds a route-less request carrying Symfony’s placeholder user-agent and 127.0.0.1 — or when the request has no user-agent or IP, it falls back to plausible.tracking.user\_agent and plausible.tracking.ip\_address. Events only fire when a site resolves, and captures are queued unless plausible.tracking.queue is false.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/plausible-for-laravel.md)
