wonderfulso / wonder-ab
Blade A/B testing for Laravel with multiple analytics integrations
Installs: 3
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/wonderfulso/wonder-ab
Requires
- php: ^8.3
- guzzlehttp/guzzle: ^7.9
- illuminate/contracts: ^12.0
- spatie/laravel-package-tools: ^1.16.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.17
- nunomaduro/collision: ^8.0
- orchestra/testbench: ^10.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-arch: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
- dev-main
- v1.1.1
- v1.1.0
- 1.0.0
- dev-82rules-patch-1
- dev-fix/license-and-baseline-updates
- dev-fix/update-track-readme
- dev-docs/fix-blade-directive-syntax
- dev-feature/webhook-goal-registration
- dev-chore/bump-version-1.0.1
- dev-fix/consolidate-migrations
- dev-dependabot/github_actions/actions/checkout-6
- dev-dependabot/github_actions/stefanzweifel/git-auto-commit-action-7
This package is auto-updated.
Last update: 2025-11-22 17:02:04 UTC
README
Blade-based A/B testing for Laravel 12+ with multiple analytics integrations.
Wonder AB makes it easy to create and manage A/B tests directly in your Laravel Blade templates with minimal configuration. Track experiments with your choice of analytics platform.
Features
- 🎯 Blade Directives - Test variants directly in your templates
- 📊 Multiple Analytics - Built-in support for Google Analytics 4, Plausible, webhooks, and more
- 🔐 Flexible Authentication - Optional authentication for reporting dashboards
- ⚡ Performance Optimized - Optional caching and database indexes
- 🎲 Weighted Variants - Control traffic distribution
- 🪆 Nested Tests - Run experiments within experiments
- 🔒 Sticky Sessions - Consistent user experience across visits
Requirements
- PHP 8.3+
- Laravel 12.0+
Installation
Install via Composer:
composer require wonderfulso/wonder-ab
Publish and run migrations:
php artisan vendor:publish --tag="wonder-ab-migrations"
php artisan migrate
Optionally publish the config file:
php artisan vendor:publish --tag="wonder-ab-config"
Quick Start
1. Basic A/B Test in Blade
@ab('hero-text') @condition('welcome') <h1>Welcome to Our Site</h1> @condition('get-started') <h1>Ready to Get Started?</h1> @track('signup')
Note: @track ends the experiment block - there is no @endab directive.
2. Track Goals
@ab('pricing-test') @condition('monthly') <button>$9/month</button> @condition('yearly') <button>$99/year</button> @track('purchase') {{-- Later in your code, when purchase is completed --}} @goal('purchase', 99.00)
How it works:
@track('purchase')- Associates this experiment with the "purchase" goal@goal('purchase', 99.00)- Records that the goal was achieved (with optional value)
3. Controller-Based Tests
use Wonderfulso\WonderAb\Facades\Ab; $variant = Ab::choice('checkout-flow', [ 'one-step' => 'single page checkout', 'multi-step' => 'wizard checkout', ]); // Use $variant to determine which view to show
4. Weighted Variants
Control traffic distribution with weights in square brackets:
@ab('feature-test') @condition('new-feature[80]') <div class="new-design">New Feature</div> @condition('old-feature[20]') <div class="old-design">Old Feature</div> @track('conversion')
Weights explained:
'new-feature[80]'- 80% probability'old-feature[20]'- 20% probability- Weights are relative:
[80]and[20]= 80:20 ratio - Without weights, all variants have equal probability
5. Nested Tests
@ab('homepage-layout') @condition('modern') <div class="modern-layout"> @ab('cta-button') @condition('green') <button class="bg-green">Sign Up</button> @condition('blue') <button class="bg-blue">Sign Up</button> @track('click') </div> @condition('classic') <div class="classic-layout">...</div> @track('engagement')
Analytics Setup
Wonder AB supports multiple analytics platforms. Configure in config/wonder-ab.php:
None (Default)
'analytics' => [ 'driver' => 'none', // Events stored in database only ],
Google Analytics 4
'analytics' => [ 'driver' => 'google', 'google' => [ 'measurement_id' => env('WONDER_AB_GA4_MEASUREMENT_ID'), 'api_secret' => env('WONDER_AB_GA4_API_SECRET'), ], ],
Plausible Analytics
'analytics' => [ 'driver' => 'plausible', 'plausible' => [ 'domain' => env('WONDER_AB_PLAUSIBLE_DOMAIN'), 'api_key' => env('WONDER_AB_PLAUSIBLE_API_KEY'), // optional ], ],
Webhook
'analytics' => [ 'driver' => 'webhook', 'webhook_url' => env('WONDER_AB_WEBHOOK_URL'), 'webhook_secret' => env('WONDER_AB_WEBHOOK_SECRET'), ],
Custom Driver
'analytics' => [ 'driver' => 'custom', 'custom_driver' => \App\Analytics\MyCustomDriver::class, ],
Webhook Goal Registration
Track server-side events (like "user signed up" or "payment completed") via webhook API:
1. Generate Webhook Secret
php artisan ab:webhook-secret
2. Configure Environment
WONDER_AB_WEBHOOK_ENABLED=true WONDER_AB_WEBHOOK_SECRET=your-generated-secret-here
3. Get Instance ID for External Apps
When redirecting users to external services (like payment processors), pass the instance ID:
use Wonderfulso\WonderAb\Facades\Ab; // Get the current user's instance ID $instanceId = Ab::getInstanceId(); // Pass it to external service return redirect("https://payment-processor.com/checkout?return_id={$instanceId}");
The external service can then send this instance ID back via webhook when the goal is achieved.
4. Send Goal Events
# Calculate HMAC-SHA256 signature payload='{"instance":"abc123","goal":"purchase","value":"99.99","timestamp":"2024-11-21T12:00:00Z","idempotency_key":"unique-id"}' signature=$(echo -n "$payload" | openssl dgst -sha256 -hmac "your-secret" | awk '{print $2}') # POST to webhook endpoint curl -X POST https://yoursite.com/api/ab/webhook/goal \ -H "Content-Type: application/json" \ -H "X-AB-Signature: $signature" \ -d "$payload"
Payload Fields:
instance(required) - User's A/B testing instance IDgoal(required) - Goal name (e.g., "purchase", "signup")value(optional) - Goal value (e.g., purchase amount)timestamp(required) - ISO 8601 timestamp (must be within 5 minutes)idempotency_key(required) - Unique request ID to prevent duplicates
Security Features:
- HMAC-SHA256 signature verification
- Timestamp validation (prevents replay attacks)
- Idempotency keys (prevents duplicate goals)
- Rate limiting (60 requests/minute per IP)
Viewing Results
CLI Commands
# View all experiments and their performance php artisan ab:report # View specific experiment php artisan ab:report hero-text # List all experiments php artisan ab:report --list # Export data to JSON php artisan ab:export # Generate webhook secret php artisan ab:webhook-secret
Web Dashboard
Visit /ab/report in your browser (requires authentication - see configuration).
Configuration
Key configuration options in config/wonder-ab.php:
return [ // Session identifier key 'cache_key' => 'wonder_ab_user', // Allow ?abid parameter to set instance ID (useful for testing) 'allow_param' => env('WONDER_AB_ALLOW_PARAM', false), 'param_rate_limit' => env('WONDER_AB_PARAM_RATE_LIMIT', 10), // Caching (improves performance) 'cache' => [ 'enabled' => env('WONDER_AB_CACHE_ENABLED', true), 'driver' => env('WONDER_AB_CACHE_DRIVER', null), // null = default 'ttl' => env('WONDER_AB_CACHE_TTL', 86400), 'prefix' => 'wonder_ab', ], // Report authentication 'report_auth' => env('WONDER_AB_REPORT_AUTH', 'none'), // none, basic, closure, middleware 'report_username' => env('WONDER_AB_REPORT_USERNAME'), 'report_password' => env('WONDER_AB_REPORT_PASSWORD'), // Analytics driver configuration 'analytics' => [ 'driver' => env('WONDER_AB_ANALYTICS_DRIVER', 'none'), // ... driver-specific config ], ];
Environment Variables
Add to your .env file:
# Analytics (outbound - send experiment data to external services) WONDER_AB_ANALYTICS_DRIVER=none # none, log, google, plausible, webhook, pivotal # Google Analytics 4 WONDER_AB_GA4_MEASUREMENT_ID= WONDER_AB_GA4_API_SECRET= # Plausible WONDER_AB_PLAUSIBLE_DOMAIN= WONDER_AB_PLAUSIBLE_API_KEY= # Webhook (outbound analytics) WONDER_AB_WEBHOOK_URL= WONDER_AB_WEBHOOK_SECRET= # Webhook Goal Registration (inbound - receive goal events from external services) WONDER_AB_WEBHOOK_ENABLED=false WONDER_AB_WEBHOOK_SECRET= # Generate with: php artisan ab:webhook-secret WONDER_AB_WEBHOOK_RATE_LIMIT=60 WONDER_AB_WEBHOOK_PATH=/ab/webhook/goal # Report Authentication WONDER_AB_REPORT_AUTH=basic WONDER_AB_REPORT_USERNAME=admin WONDER_AB_REPORT_PASSWORD=secret # Optional: Performance WONDER_AB_CACHE_ENABLED=true WONDER_AB_ALLOW_PARAM=false
Testing
composer test composer analyse # PHPStan composer format # Laravel Pint
Security
- Rate limiting on parameter overrides
- JSON storage (no unserialize vulnerabilities)
- Webhook signature verification
- Optional authentication for reports
Documentation
For advanced usage, custom drivers, and architecture details, see DEVELOPER.md.
License
The MIT License (MIT). See LICENSE.md for details.
Credits
Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions