Skip to content
Documentation menu: Laravel

Laravel integration

Add theBizness.ai analytics to your Laravel application with elegant Blade templates and environment configuration.

Setup time

5 minutes

Difficulty

Medium

Performance

Elegant

Choose your implementation method

Blade layout method

Add analytics to your main layout template with environment configuration

Step 1: Environment configuration

Add these variables to your .env file:

# .env
THEBIZNESS_ENABLED=true
THEBIZNESS_WEBSITE_ID=your-website-id
THEBIZNESS_DOMAIN=yourdomain.com

Step 2: Create the config file

Create config/analytics.php:

<?php
// config/analytics.php

return [
    'thebizness' => [
        'enabled' => env('THEBIZNESS_ENABLED', false),
        'website_id' => env('THEBIZNESS_WEBSITE_ID'),
        'domain' => env('THEBIZNESS_DOMAIN'),
        'script_url' => env('THEBIZNESS_SCRIPT_URL', 'https://thebizness.ai/js/script.js'),
        // Route patterns the middleware should skip, for example ['admin/*', 'horizon*']
        'exclude' => [],
    ],
];

Step 3: Update the layout template

Update your main layout file:

{{-- resources/views/layouts/app.blade.php --}}
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Scripts -->
    @vite(['resources/css/app.css', 'resources/js/app.js'])
    
    <!-- theBizness Analytics -->
    @if(config('analytics.thebizness.enabled', false) && config('analytics.thebizness.website_id'))
        <script 
            async 
            defer 
            data-website-id="{{ config('analytics.thebizness.website_id') }}" 
            data-domain="{{ config('analytics.thebizness.domain') ?: request()->getHost() }}" 
            src="https://thebizness.ai/js/script.js">
        </script>
    @endif
</head>
<body>
    <div id="app">
        @yield('content')
    </div>
</body>
</html>
Laravel best practices
  • • Environment-based configuration
  • • Conditional loading based on settings
  • • Auto-detects domain from request
  • • Easy to disable for development

Middleware implementation

Automatically inject analytics script using middleware

Create the analytics middleware

<?php
// app/Http/Middleware/AnalyticsMiddleware.php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Http\Response;

class AnalyticsMiddleware
{
    public function handle(Request $request, Closure $next)
    {
        $response = $next($request);

        if (! $this->shouldInjectAnalytics($request, $response)) {
            return $response;
        }

        // Streamed and file responses have no string body, so getContent() can return false
        $content = $response->getContent();

        if (! is_string($content)) {
            return $response;
        }

        // Inject before closing head tag
        $content = str_replace('</head>', $this->getAnalyticsScript() . '</head>', $content);
        $response->setContent($content);

        // Keep an existing Content-Length header accurate
        if ($response->headers->has('Content-Length')) {
            $response->headers->set('Content-Length', (string) strlen($content));
        }

        return $response;
    }

    private function shouldInjectAnalytics(Request $request, $response): bool
    {
        return config('analytics.thebizness.enabled', false) &&
               // Only plain responses. StreamedResponse and BinaryFileResponse are not Illuminate\Http\Response
               $response instanceof Response &&
               $response->getStatusCode() === 200 &&
               $request->route() &&
               ! $request->expectsJson() &&
               // Skip the route patterns listed under 'exclude' in config/analytics.php
               ! $request->is(...(config('analytics.thebizness.exclude') ?? [])) &&
               // Compressed bodies cannot be edited as text
               ! $response->headers->has('Content-Encoding') &&
               str_contains($response->headers->get('Content-Type', ''), 'text/html');
    }

    private function getAnalyticsScript(): string
    {
        $websiteId = config('analytics.thebizness.website_id');
        $domain = config('analytics.thebizness.domain') ?: request()->getHost();
        $scriptUrl = config('analytics.thebizness.script_url');

        if (!$websiteId) {
            return '';
        }

        return sprintf(
            '<script async defer data-website-id="%s" data-domain="%s" src="%s"></script>%s',
            e($websiteId),
            e($domain),
            e($scriptUrl),
            PHP_EOL
        );
    }
}

Register the middleware

Laravel 11 and later: add the middleware to the web group in bootstrap/app.php:

<?php
// bootstrap/app.php (Laravel 11 and later)

use App\Http\Middleware\AnalyticsMiddleware;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    // ... keep your existing withRouting() and withExceptions() calls
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->web(append: [
            AnalyticsMiddleware::class,
        ]);
    })
    ->create();

Laravel 10 and earlier: add App\Http\Middleware\AnalyticsMiddleware::class to the 'web' array in $middlewareGroups in app/Http/Kernel.php.

Blade component

Reusable Blade component for analytics

Create the component

{{-- resources/views/components/analytics.blade.php --}}
@if(config('analytics.thebizness.enabled', false) && config('analytics.thebizness.website_id'))
    <script 
        async 
        defer 
        data-website-id="{{ config('analytics.thebizness.website_id') }}" 
        data-domain="{{ config('analytics.thebizness.domain') ?: request()->getHost() }}" 
        src="{{ config('analytics.thebizness.script_url', 'https://thebizness.ai/js/script.js') }}">
    </script>
@endif

{{-- Usage in layouts: --}}
{{-- <x-analytics /> --}}

Helper class and Artisan command

Advanced implementation with helper class and setup command

Analytics helper class

<?php
// app/Helpers/AnalyticsHelper.php

namespace App\Helpers;

class AnalyticsHelper
{
    public static function isEnabled(): bool
    {
        return config('analytics.thebizness.enabled', false) && 
               !empty(config('analytics.thebizness.website_id'));
    }
    
    public static function getTrackingScript(): string
    {
        if (!self::isEnabled()) {
            return '';
        }
        
        $websiteId = config('analytics.thebizness.website_id');
        $domain = config('analytics.thebizness.domain') ?: request()->getHost();
        $scriptUrl = config('analytics.thebizness.script_url', 'https://thebizness.ai/js/script.js');

        return sprintf(
            '<script async defer data-website-id="%s" data-domain="%s" src="%s"></script>',
            e($websiteId),
            e($domain),
            e($scriptUrl)
        );
    }
}

// Add to composer.json autoload.files:
// "files": ["app/Helpers/AnalyticsHelper.php"]

Artisan setup command

<?php
// app/Console/Commands/SetupAnalytics.php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class SetupAnalytics extends Command
{
    protected $signature = 'analytics:setup {website-id} {domain?}';
    protected $description = 'Set up theBizness analytics configuration';
    
    public function handle()
    {
        $websiteId = $this->argument('website-id');
        $domain = $this->argument('domain') ?: parse_url(config('app.url'), PHP_URL_HOST);
        
        // Update .env file
        $this->updateEnvFile([
            'THEBIZNESS_ENABLED' => 'true',
            'THEBIZNESS_WEBSITE_ID' => $websiteId,
            'THEBIZNESS_DOMAIN' => $domain,
        ]);
        
        $this->info('Analytics configuration updated successfully!');
        $this->info("Website ID: {$websiteId}");
        $this->info("Domain: {$domain}");
    }
    
    private function updateEnvFile(array $values): void
    {
        $envFile = base_path('.env');
        $envContent = file_get_contents($envFile);
        
        foreach ($values as $key => $value) {
            $pattern = "/^{$key}=.*/m";
            $replacement = "{$key}={$value}";
            
            if (preg_match($pattern, $envContent)) {
                $envContent = preg_replace($pattern, $replacement, $envContent);
            } else {
                $envContent .= "\n{$replacement}";
            }
        }
        
        file_put_contents($envFile, $envContent);
    }
}

Usage

# Setup analytics with Artisan command
php artisan analytics:setup your-website-id yourdomain.com

# Use in Blade templates
{!! AnalyticsHelper::getTrackingScript() !!}

Verify installation

Test your Laravel analytics integration

Development check

  1. 1. Run php artisan serve to check that the page loads
  2. 2. Visit your Laravel app
  3. 3. Check browser DevTools Network tab
  4. 4. Look for the script.js request. The console shows a "Tracking disabled on localhost" warning here, which is expected

Configuration check

  1. 1. Run php artisan config:cache
  2. 2. Check config('analytics.thebizness')
  3. 3. Verify environment variables
  4. 4. Test different routes
Laravel-specific tips
  • • The tracker does nothing on localhost, *.local, *.test, private IP addresses or file:// pages. It logs a "Tracking disabled on localhost" warning in the console. Verify on a publicly reachable domain.
  • • Use different configurations for different environments
  • • Consider disabling analytics in local development
  • • Cache config in production: php artisan config:cache
  • • Test with both authenticated and guest users
  • • If your site sends a Content-Security-Policy header, allow https://thebizness.ai in script-src and connect-src. Blocked requests show only as CSP errors in the browser console

Laravel integration complete

Your Laravel application is now tracking analytics with elegant configuration. Here's what to explore next:

Revenue attribution

Connect Stripe or send a purchase event from your order-complete page

Custom events

Send events from the browser with window.thebizness(...). See the API reference

Server-side reporting

Report sales from your backend with Laravel's HTTP client and your ingest secret as a Bearer token. Keep the secret in your .env file