PHPackages                             wonderfulso/wonder-ab - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. wonderfulso/wonder-ab

ActiveLibrary[Testing &amp; Quality](/categories/testing)

wonderfulso/wonder-ab
=====================

Blade A/B testing for Laravel with multiple analytics integrations

v1.1.1(5mo ago)09[3 PRs](https://github.com/wonderfulso/wonder-ab/pulls)MITPHPPHP ^8.3CI passing

Since Nov 22Pushed 1mo agoCompare

[ Source](https://github.com/wonderfulso/wonder-ab)[ Packagist](https://packagist.org/packages/wonderfulso/wonder-ab)[ Docs](https://github.com/wonderfulso/wonder-ab)[ RSS](/packages/wonderfulso-wonder-ab/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (3)Dependencies (10)Versions (13)Used By (0)

Wonder AB
=========

[](#wonder-ab)

**Blade-based A/B testing for Laravel 12+ with multiple analytics integrations.**

[![Tests](https://github.com/wonderfulso/wonder-ab/actions/workflows/tests.yml/badge.svg)](https://github.com/wonderfulso/wonder-ab/actions)[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](https://opensource.org/licenses/MIT)

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
--------

[](#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
------------

[](#requirements)

- PHP 8.3+
- Laravel 12.0+

Installation
------------

[](#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
-----------

[](#quick-start)

### 1. Basic A/B Test in Blade

[](#1-basic-ab-test-in-blade)

```
@ab('hero-text')
    @condition('welcome')
        Welcome to Our Site
    @condition('get-started')
        Ready to Get Started?
@track('signup')
```

**Note**: `@track` ends the experiment block - there is no `@endab` directive.

### 2. Track Goals

[](#2-track-goals)

```
@ab('pricing-test')
    @condition('monthly')
        $9/month
    @condition('yearly')
        $99/year
@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

[](#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

[](#4-weighted-variants)

Control traffic distribution with weights in square brackets:

```
@ab('feature-test')
    @condition('new-feature[80]')
        New Feature
    @condition('old-feature[20]')
        Old Feature
@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

[](#5-nested-tests)

```
@ab('homepage-layout')
    @condition('modern')

            @ab('cta-button')
                @condition('green')
                    Sign Up
                @condition('blue')
                    Sign Up
                @track('click')

    @condition('classic')
        ...
@track('engagement')
```

Analytics Setup
---------------

[](#analytics-setup)

Wonder AB supports multiple analytics platforms. Configure in `config/wonder-ab.php`:

### None (Default)

[](#none-default)

```
'analytics' => [
    'driver' => 'none', // Events stored in database only
],
```

### Google Analytics 4

[](#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

[](#plausible-analytics)

```
'analytics' => [
    'driver' => 'plausible',
    'plausible' => [
        'domain' => env('WONDER_AB_PLAUSIBLE_DOMAIN'),
        'api_key' => env('WONDER_AB_PLAUSIBLE_API_KEY'), // optional
    ],
],
```

### Webhook

[](#webhook)

```
'analytics' => [
    'driver' => 'webhook',
    'webhook_url' => env('WONDER_AB_WEBHOOK_URL'),
    'webhook_secret' => env('WONDER_AB_WEBHOOK_SECRET'),
],
```

### Custom Driver

[](#custom-driver)

```
'analytics' => [
    'driver' => 'custom',
    'custom_driver' => \App\Analytics\MyCustomDriver::class,
],
```

Webhook Goal Registration
-------------------------

[](#webhook-goal-registration)

Track server-side events (like "user signed up" or "payment completed") via webhook API:

### 1. Generate Webhook Secret

[](#1-generate-webhook-secret)

```
php artisan ab:webhook-secret
```

### 2. Configure Environment

[](#2-configure-environment)

```
WONDER_AB_WEBHOOK_ENABLED=true
WONDER_AB_WEBHOOK_SECRET=your-generated-secret-here
```

### 3. Get Instance ID for External Apps

[](#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

[](#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 ID
- `goal` (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
---------------

[](#viewing-results)

### CLI Commands

[](#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

[](#web-dashboard)

Visit `/ab/report` in your browser (requires authentication - see configuration).

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
---------------------

[](#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
-------

[](#testing)

```
composer test
composer analyse  # PHPStan
composer format   # Laravel Pint
```

Security
--------

[](#security)

- Rate limiting on parameter overrides
- JSON storage (no unserialize vulnerabilities)
- Webhook signature verification
- Optional authentication for reports

Documentation
-------------

[](#documentation)

For advanced usage, custom drivers, and architecture details, see [DEVELOPER.md](DEVELOPER.md).

License
-------

[](#license)

The MIT License (MIT). See [LICENSE.md](LICENSE.md) for details.

Credits
-------

[](#credits)

- [Rulian Estivalletti](https://github.com/ruliancrafter)
- [All Contributors](../../contributors)

Support
-------

[](#support)

- **Issues**: [GitHub Issues](https://github.com/wonderfulso/wonder-ab/issues)
- **Discussions**: [GitHub Discussions](https://github.com/wonderfulso/wonder-ab/discussions)

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance82

Actively maintained with recent releases

Popularity5

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity57

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 83.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

172d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/65c27a46e9e70beb8aaa7c6c8da6643d3fbc6a32deeb5ea1c9191e6f509a5af5?d=identicon)[wonderfulso](/maintainers/wonderfulso)

---

Top Contributors

[![82rules](https://avatars.githubusercontent.com/u/2653133?v=4)](https://github.com/82rules "82rules (20 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (3 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (1 commits)")

---

Tags

laravelanalyticssplit testingab-testingwonder-ab

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/wonderfulso-wonder-ab/health.svg)

```
[![Health](https://phpackages.com/badges/wonderfulso-wonder-ab/health.svg)](https://phpackages.com/packages/wonderfulso-wonder-ab)
```

###  Alternatives

[spatie/laravel-health

Monitor the health of a Laravel application

85810.0M83](/packages/spatie-laravel-health)[vormkracht10/laravel-mails

Laravel Mails can collect everything you might want to track about the mails that has been sent by your Laravel app.

24149.7k](/packages/vormkracht10-laravel-mails)[spatie/laravel-visit

Quickly visit any route of your Laravel app

15614.6k](/packages/spatie-laravel-visit)[sunchayn/nimbus

A Laravel package providing an in-browser API client with automatic schema generation, live validation, and built-in authentication with a touch of Laravel-tailored magic for effortless API testing.

29428.0k](/packages/sunchayn-nimbus)[muhammadhuzaifa/telescope-guzzle-watcher

Telescope Guzzle Watcher provide a custom watcher for intercepting http requests made via guzzlehttp/guzzle php library. The package uses the on\_stats request option for extracting the request/response data. The watcher intercept and log the request into the Laravel Telescope HTTP Client Watcher.

98239.8k1](/packages/muhammadhuzaifa-telescope-guzzle-watcher)[spatie/laravel-mailcoach-sdk

An SDK to easily work with the Mailcoach API in Laravel apps

41290.2k1](/packages/spatie-laravel-mailcoach-sdk)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
