Laravel Installation Guide
Last researched 2026-08-26
This is the canonical Virent installation guide for Laravel applications.
Research Notes#
- Laravel 13.x configures middleware in
bootstrap/app.php. - Middleware can run before and after
$next($request), which makes final response status available. - The HTTP facade is the recommended built-in client for outbound server requests.
Primary references:
- https://laravel.com/docs/13.x/middleware
- https://laravel.com/docs/13.x/http-client
Human Analytics#
Add the script to the shared Blade layout.
TXT
<!-- resources/views/layouts/app.blade.php --><head> <meta charset="utf-8"> <script defer data-write-key="vha_pk_..." src="https://app.virent.app/js/script.js" ></script> @vite(['resources/css/app.css', 'resources/js/app.js'])</head>Best practices:
- Install in the layout used by public web routes.
- Use only the publishable browser key in Blade output.
- Add nonce attributes if the app's CSP requires them.
- Clear compiled views if the deployed page does not update.
Verification:
SH
php artisan view:clear- Open a public page and inspect the head.
- Check Network for the Virent script and pageview request.
- Refresh Human Analytics status.
Troubleshooting:
- If some pages are not tracked, find additional Blade layouts.
- If CSP blocks Virent, update Laravel or proxy headers.
- If cached views hide the change, run
php artisan view:clear.
AI Analytics#
Set server values:
ENV
VIRENT_SITE_ID=site_...VIRENT_INGEST_SECRET=vha_sk_...VIRENT_INGEST_ENDPOINT=https://app.virent.app/v1/ingest/botCreate middleware:
TXT
<?phpnamespace App\Http\Middleware;use Closure;use Illuminate\Http\Request;use Illuminate\Support\Facades\Http;use Symfony\Component\HttpFoundation\Response;class TrackVirentCrawler{ public function handle(Request $request, Closure $next): Response { return $next($request); } public function terminate(Request $request, Response $response): void { $userAgent = $request->userAgent() ?? ''; if ( preg_match('/\.(?:png|jpg|jpeg|gif|svg|ico|webp|css|js|map|txt|xml)$/i', $request->path()) || ! preg_match('/GPTBot|OAI-SearchBot|ChatGPT-User|ClaudeBot|claudebot|Claude-Web|Claude-User|Claude-SearchBot|PerplexityBot|PerplexityBot\/|Perplexity-User|Perplexity-User\/|Google-CloudVertexBot|DeepSeekBot|DeepSeekSpider|CCBot|Applebot|Bytespider|meta-externalagent|meta-webindexer|meta-externalfetcher|Amazonbot|DuckAssistBot|PetalBot|YouBot/i', $userAgent) ) { return; } try { Http::withHeaders([ 'x-api-key' => env('VIRENT_INGEST_SECRET'), ])->timeout(2)->post(env('VIRENT_INGEST_ENDPOINT'), [ 'siteId' => env('VIRENT_SITE_ID'), 'url' => $request->fullUrl(), 'host' => $request->getHost(), 'path' => '/' . ltrim($request->path(), '/'), 'method' => $request->method(), 'referer' => $request->headers->get('referer'), 'userAgent' => $userAgent, 'statusCode' => $response->getStatusCode(), 'requestId' => (string) str()->uuid(), 'timestamp' => now()->toIso8601String(), ]); } catch (\Throwable) { // Analytics must never change the application response. } }}Register it:
TXT
// bootstrap/app.phpuse App\Http\Middleware\TrackVirentCrawler;use Illuminate\Foundation\Configuration\Middleware;->withMiddleware(function (Middleware $middleware): void { $middleware->web(append: [ TrackVirentCrawler::class, ]);})Best practices:
- Append to Laravel's
webmiddleware group for public page routes. - Do not include API routes unless AI crawler traffic to APIs should be tracked.
- Use terminable middleware so telemetry is sent after the application response with its final status.
- Clear config cache after env changes.
Verification:
SH
php artisan optimize:clearcurl -A "GPTBot" https://your-domain.com/- Confirm Laravel sends an outbound request to Virent.
- Refresh AI Analytics status.
Troubleshooting:
- If middleware does not run, confirm it is appended in
bootstrap/app.php. - If env values are missing, clear config cache.
- If high-traffic pages slow down, lower timeout values or queue telemetry.