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 Amplitude Laravel Package

francescomalatesta/laravel-amplitude

Laravel Amplitude provides a simple integration for sending analytics events from Laravel applications to Amplitude, with a clean API for tracking user activity and custom events.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and wire it up

composer require francescomalatesta/laravel-amplitude
  • On Laravel 5.5+ the service provider and Amplitude facade are auto-discovered. On older versions, register Malatesta\LaravelAmplitude\LaravelAmplitudeServiceProvider in config/app.php and add the alias 'Amplitude' => Malatesta\LaravelAmplitude\Facades\Amplitude::class.
  • Publish the config and put your project key in .env:
php artisan vendor:publish --provider="Malatesta\LaravelAmplitude\LaravelAmplitudeServiceProvider"
AMPLITUDE_API_KEY=your_project_api_key

Look here first

  1. config/amplitude.php — this is where the API key and any HTTP/client options live. Read it before writing any tracking code; it determines whether the package reads from env() or expects a hard-coded key.
  2. The package's src/ directory — it is small (a service class, a facade, a provider, a config). You can read the whole thing in ten minutes, and you should, because the public surface is only a handful of methods (sendEvent, and typically an identify/user-properties call).
  3. The README's usage block — method signatures here are thin wrappers over Amplitude's HTTP API v2, so the argument order (user id, event name, properties array) is the thing to confirm.

First use case

Track a signup so you can confirm the pipe works end-to-end:

use Malatesta\LaravelAmplitude\Facades\Amplitude;

Amplitude::sendEvent(
    (string) $user->id,
    'Signed Up',
    ['plan' => $user->plan, 'source' => 'web']
);

Then open Amplitude → User Activity / Events and confirm the event landed within a minute or two. Do this before building out twenty events — you want to validate the key, the environment, and the payload shape once.

Implementation Patterns

Wrap it — don't sprinkle the facade everywhere. The facade is a static call into a thin HTTP client. Put a single AnalyticsService (or a small set of typed methods) in front of it so the rest of the app doesn't know the package exists:

class Analytics
{
    public function track(User $user, string $event, array $props = []): void
    {
        Amplitude::sendEvent((string) $user->id, $event, $props + [
            'environment' => app()->environment(),
        ]);
    }
}

This gives you one place to add queuing, sampling, environment prefixes, and error swallowing later.

Drive it from domain events, not controllers. The cleanest integration in a Laravel app is event → listener, because tracking is a side effect and shouldn't sit in the request path:

// app/Listeners/TrackUserRegistered.php
public function handle(UserRegistered $event): void
{
    $this->analytics->track($event->user, 'Signed Up', [
        'plan' => $event->user->plan,
    ]);
}

Register the listener with ShouldQueue so the HTTP call happens on a worker. This is the single highest-value pattern with this package.

Model the event taxonomy before you instrument. Amplitude rewards a consistent schema: one naming convention (Signed Up, Order Completed — pick sentence case or snake_case and stick to it), a stable set of user properties, and reserved $-prefixed properties for Amplitude's own semantics. Define the event names as constants or an enum so typos don't silently create phantom events.

Use reserved properties deliberately. Amplitude understands $revenue, $price, $quantity, $productId for revenue tracking and $insert_id for deduplication. If you're sending purchases, use these — don't invent order_total and then wonder why revenue charts are empty.

Identify users once, then track. For logged-in users, send an identify/user-properties call on login or profile update (name, plan, company, signup date) so Amplitude can segment events later. Then every event carries only the user id. Avoid stuffing the full user profile into every event payload — it bloats the request and drifts out of sync.

Guard anonymous traffic. Amplitude needs either a user_id or a device_id. Pre-login events should be tracked against a device/session id, and Amplitude's SDKs normally handle the merge on identify. This package is a server-side client with no cookie/device handling — you have to supply an identifier yourself. If pre-login tracking matters, capture a UUID in a cookie and pass it.

Test with a fake. Because everything funnels through your Analytics wrapper, you can bind a fake in tests and assert on the events your app would send, without hitting Amplitude:

$this->swap(Analytics::class, $fake = new FakeAnalytics());
// ... act ...
$fake->assertTracked('Signed Up', ['plan' => 'pro']);

Only the wrapper's own test should touch the real facade.

Gotchas and Tips

The client is synchronous. sendEvent performs a blocking HTTP request. Called from a controller, that's tens to hundreds of milliseconds added to every response, and a slow/hanging Amplitude endpoint becomes your outage. Always push it to a queued listener or job. If you can't queue, at minimum wrap calls in try/catch and set a short timeout on the underlying HTTP client.

One request per event, no batching. Amplitude's HTTP API has a /batch endpoint for sending many events in one call. This package (being a thin, low-activity wrapper) sends individual events. For high-volume flows — imports, backfills, bulk state changes — you'll either accept N requests or write your own batch call. Don't fire a tracking event inside a loop over 10,000 rows.

Failures are easy to miss. A wrong API key or malformed payload typically surfaces as a non-2xx response that the package may or may not throw on. Decide explicitly what you want: silent-and-logged (usual for analytics) or loud (useful in staging). Log the response body on failure at minimum, and add an environment property to every event so staging events don't pollute production dashboards — or use separate Amplitude projects per environment.

No retries, no persistence. If the HTTP call fails, the event is gone. Analytics is usually lossy-by-design and that's fine, but don't use this package as your source of truth for anything billable — keep your own database records and treat Amplitude as a read-only mirror.

Config quirks. The published config is the authority on the env var name; older releases have used variations on AMPLITUDE_API_KEY. If config:cache is in play, remember env changes require a re-cache. Also check whether the config expects the key at boot time — a missing key may fail silently rather than throwing, which is confusing to debug.

Reserved names and typing. Property keys starting with $ are reserved by Amplitude. Event and property names are case-sensitive and space-sensitive, so Signed Up and signed up are different events — a common source of "where did my data go?" Validate names in your wrapper in non-production.

Debugging flow. When an event doesn't appear: (1) dump the exact payload and confirm the user id is a non-empty string, not an int-cast-to-empty; (2) check the HTTP response status and body; (3) search Amplitude's User Activity for that user id — if the user doesn't exist, the event never arrived; (4) verify you're looking at the right Amplitude project for that API key.

Maturity risk. Twelve stars and low activity means: pin the version in composer.json, check the package's Laravel/HTTP-client compatibility against your app before upgrading either, and be prepared to fork. The extension points are all on your side of the boundary — publish the config, wrap the facade, and if you ever need batching or retries, swap the wrapper's internals for a direct call to Amplitude's HTTP API rather than waiting on the package. Its value is the facade and config wiring, not the client logic, and that's a few dozen lines to replace.

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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource