> AI agents: this is one page from PostHog's docs. Full index of Markdown docs for LLMs: https://posthog.com/llms.txt # Laravel PostHog integrates with Laravel through the [PostHog PHP SDK](/docs/libraries/php.md). This page covers Laravel-specific setup. For SDK features such as event capture, identifying users, feature flags, group analytics, and configuration options, see the [PHP SDK docs](/docs/libraries/php.md). ## Installation Install the PHP SDK as described in the [PHP installation guide](/docs/libraries/php.md#installation), then add your project token and host to `.env`: .env ```bash POSTHOG_API_KEY= POSTHOG_HOST=https://us.i.posthog.com ``` Add PostHog to Laravel's services config: config/services.php ```php 'posthog' => [ 'api_key' => env('POSTHOG_API_KEY'), 'host' => env('POSTHOG_HOST', 'https://us.i.posthog.com'), ], ``` Initialize PostHog in the `boot` method of `app/Providers/AppServiceProvider.php`: app/Providers/AppServiceProvider.php ```php config('services.posthog.host'), ] ); } } ``` ## Request context middleware Client SDKs such as [PostHog JS](/docs/libraries/js.md) can send tracing headers to your Laravel backend. Configure [`tracing_headers`](/docs/libraries/js/config.md#tracing-headers) for your Laravel backend hostname so browser requests include the session and distinct ID headers. The PHP SDK can read `X-PostHog-Distinct-Id` and `X-PostHog-Session-Id` headers and apply them to events captured during the request. Tracing headers are client-controlled analytics context, not authentication or authorization. For security-sensitive server-side events or decisions, pass an authenticated `distinctId` explicitly, such as `auth()->id()`. For the lower-level context APIs, see the [PHP request context docs](/docs/libraries/php.md#request-context). Add middleware like this: app/Http/Middleware/PostHogRequestContext.php ```php headers->all()); $context['properties'] = array_merge( $context['properties'] ?? [], array_filter([ '$current_url' => $request->fullUrl(), '$request_method' => $request->method(), '$request_path' => $request->getPathInfo(), '$user_agent' => $request->userAgent(), '$ip' => $request->ip(), ], static fn ($value): bool => $value !== null && $value !== '') ); return PostHog::withContext( $context, static fn (): Response => $next($request), ['fresh' => true] ); } } ``` Register this middleware using your Laravel version's normal middleware registration. ## Error tracking in Laravel The PHP SDK supports [error tracking](/docs/libraries/php.md#error-tracking), but Laravel handles most request exceptions before they become uncaught PHP exceptions. Capture Laravel-reported exceptions explicitly. In Laravel 11 and later, add a report callback in `bootstrap/app.php`: bootstrap/app.php ```php use Illuminate\Foundation\Configuration\Exceptions; use PostHog\PostHog; use Throwable; ->withExceptions(function (Exceptions $exceptions): void { $exceptions->report(function (Throwable $e): void { if (! config('services.posthog.api_key')) { return; } PostHog::captureException( $e, auth()->id() !== null ? (string) auth()->id() : null, [ '$current_url' => request()->fullUrl(), '$request_method' => request()->method(), ] ); }); }) ``` For older Laravel versions, call `PostHog::captureException()` from your exception handler's `report` method. ## Long-running processes In normal PHP request lifecycles, queued events flush when the client is destroyed. In long-running Laravel processes such as queue workers, Horizon, or Octane, call `PostHog::flush()` after capturing important events or at the end of a job/request. If you prefer immediate delivery in queue workers, configure the PHP SDK with `batch_size` set to `1` for those workers: PHP ```php PostHog::init( '', [ 'host' => config('services.posthog.host'), 'batch_size' => 1, ] ); ``` ## Next steps See the [PHP SDK docs](/docs/libraries/php.md) for usage examples and the full API reference. ### Still have questions? Ask PostHog AI ### Was this page useful? HelpfulCould be better