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

jeffersongoncalves/laravel-segment

Laravel Segment offers a simple integration for Segment analytics, letting you track events, identify users, and send server-side data through Segment’s API with clean, configurable Laravel support.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package and publish its config:

composer require <vendor>/laravel-segment
php artisan vendor:publish --tag=segment-config

Add the credentials you actually need to .env — you do not need all three:

SEGMENT_WRITE_KEY=...        # Tracking API: track / identify / page / batch
SEGMENT_ACCESS_TOKEN=...     # Profile API (Personas)
SEGMENT_SPACE_ID=...         # Profile API (Personas)

First place to look is config/segment.php. It is the contract for the whole package: the three keys above map to three distinct Segment surfaces, and the InvalidArgumentException you get at call time is almost always a key you didn't set. Read that file before reading any other source.

The first use case to wire up is a single track call on a domain event you already have — a registration or order completion:

Segment::track([
    'userId' => $user->id,
    'event'  => 'Order Completed',
    'properties' => ['order_id' => $order->id, 'revenue' => $order->total],
]);

If that round-trips into your Segment debugger, the transport, key, and payload shape are all correct and everything else is just payload design.

Implementation Patterns

Wrap the client, don't sprinkle it. Build one thin app-level service (Analytics) that owns the Segment client and exposes intent-revealing methods (orderCompleted(), userRegistered()). Every call site then depends on your class, not the package — which makes the inevitable swap to a different CDP a one-file change, and gives you a place to centralise anonymousId/userId resolution and PII scrubbing.

Drive it from domain events, not controllers. Fire a Laravel event from your action/service, and let a queued listener call Segment. This keeps HTTP calls out of the request cycle and means the same event can feed Segment, your logs, and anything else later.

Always queue. These are synchronous HTTP calls built on Laravel's Http client. Under load, an in-request track adds Segment's latency (and timeout budget) to every user-facing response. Implement ShouldQueue on listeners, or wrap calls in a job with tries/backoff.

Choose identify vs track deliberately. identify sets traits on a user profile and is the right place for durable attributes (plan, company, created_at). track is for things that happened. Sending traits on every track call is a common and costly mistake — it bloats payloads and creates profile churn.

Use batch for anything loop-shaped. Backfills, imports, and nightly syncs should never be one call per record. Chunk your collection, build the array of messages, and send in batches — then inspect the response (see Gotchas) before marking rows as synced.

Profile API is a separate data plane. profileTraits and profileEvents talk to Personas, need SEGMENT_ACCESS_TOKEN + SEGMENT_SPACE_ID, and do not share the write key. Do not assume a working track implies working profileTraits — they fail independently, and only in the environments where you configured the Personas credentials.

Test with Http::fake(). Because it sits on Laravel's HTTP client, you get Http::fake() and Http::assertSent() for free. Assert on the URL, the write key in the body, and the message shape — that's enough to catch the payload regressions that matter.

Gotchas and Tips

Credentials fail at call time, not boot time. A missing key throws InvalidArgumentException from the method that needs it. That means a misconfigured staging deploy looks healthy until the first event fires. Add a small config assertion to your deploy smoke test, and consider failing fast in a service provider for non-local environments.

Batch returns 200 with per-message errors. Segment's batch endpoint accepts the request and reports individual failures in the response body. Checking only $response->successful() will silently drop events. Parse the response, log errors, and decide whether to re-queue.

Retries duplicate events. Segment has no automatic dedupe on the tracking endpoint — if you enable ->retry() or a job re-runs after a timeout, users get double-counted. Set a stable messageId on each message if you're going to retry, or make your jobs non-retrying and log failures to a dead-letter table.

anonymousId vs userId. Pre-login events need an anonymousId; post-login events need userId. Carry the anonymous ID through your session and send it on the identify call, or you'll split one human into two profiles and spend a week reconciling them.

Don't put raw PII in traits. Traits and properties are replicated widely downstream and are hard to delete. Send IDs and hashed values where you can; know your deletion path before someone files a GDPR request.

Keep env() in the config file. Standard Laravel rule, but it bites here specifically because credentials are the whole failure mode — if you call env() in a service class it returns null the moment someone runs config:cache.

Version constraints are tight. PHP 8.2+ and Laravel 12/13 only. Before adopting, confirm your app and any packages that pin laravel/framework are already on 12+; there's no graceful fallback for older projects.

Extension points are thin by design. The package is a client, not a pipeline. If you need per-event transformation, sampling, or destination routing, do it above the package (in your wrapper service or listeners) rather than fighting it — Segment itself is the right place for destination-level transformations.

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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle