npm package: @gemx-dev/experiment
Description: AB Testing Section Block Components for multiple frameworks with tracking
Author: gemx-dev
Latest version: 3.5.17

# @gemx-dev/experiment (develop)

<!-- [![npm version](https://badge.fury.io/js/%40gemx%ab-2Fexperiment.svg)](https://badge.fury.io/js/%40gemx%ab-2Fexperiment)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/) -->

> **The most developer-friendly A/B testing library for modern web applications**

A powerful, framework-agnostic A/B testing library that works seamlessly with React, Vue, Angular, and vanilla JavaScript. Built with TypeScript for type safety and designed for optimal developer experience.

## ✨ Features

- 🚀 **Zero Configuration** - Start testing in minutes with our intuitive API
- 🛡️ **Type-Safe** - Full TypeScript support with intelligent autocompletion
- 🌐 **Framework Agnostic** - Works with React, Vue, Angular, or vanilla JavaScript
- 📊 **Built-in Analytics** - Seamless integration with Google Analytics, Mixpanel, and more
- 🎯 **Smart Targeting** - Device, location, and custom targeting rules
- 🔧 **Developer Experience** - Built-in debugging, error handling, and clean APIs
- 📦 **Lightweight** - Minimal bundle size with tree-shaking support
- 🔄 **Persistent** - User assignments persist across sessions
- 🎨 **Flexible** - Support for weighted variants and custom metadata

## 📦 Installation

```bash
# npm
npm install @gemx-dev/experiment

# yarn
yarn add @gemx-dev/experiment

# pnpm
pnpm add @gemx-dev/experiment
```

## 🚀 Quick Start

### React

```tsx
import { GxExperimentWrapper, getVariant } from '@gemx-dev/experiment/react';

const variant = getVariant({
  experimentId: 'hero-test',
  variants: [
    { name: 'A', weight: 0.5 },
    { name: 'B', weight: 0.5 },
  ],
});

function HeroSection() {
  return (
    <GxExperimentWrapper variant={variant} experimentId="hero-test" onTrack={(event, data) => console.log(event, data)}>
      <div data-variant="A">
        <h1>Welcome to our amazing product!</h1>
        <button>Get Started</button>
      </div>
      <div data-variant="B">
        <h1>Discover something incredible!</h1>
        <button>Try Now</button>
      </div>
    </GxExperimentWrapper>
  );
}
```

### Vue

```vue
<template>
  <GxExperimentWrapper :variant="variant" experiment-id="hero-test" @track="handleTrack">
    <div data-variant="A">
      <h1>Welcome to our amazing product!</h1>
      <button>Get Started</button>
    </div>
    <div data-variant="B">
      <h1>Discover something incredible!</h1>
      <button>Try Now</button>
    </div>
  </GxExperimentWrapper>
</template>

<script setup lang="ts">
import { getVariant } from '@gemx-dev/experiment';
import { GxExperimentWrapper } from '@gemx-dev/experiment/vue';
import { ref } from 'vue';

const variant = ref(
  getVariant({
    experimentId: 'hero-test',
    variants: [
      { name: 'A', weight: 0.5 },
      { name: 'B', weight: 0.5 },
    ],
  }),
);

const handleTrack = (event: string, data: any) => {
  console.log(`Event: ${event}`, data);
};
</script>
```

### Vanilla JavaScript / HTML

```html
<!DOCTYPE html>
<html>
  <head>
    <script src="https://unpkg.com/@gemx-dev/experiment/dist/index.js"></script>
  </head>
  <body>
    <gx-experiment-wrapper variant="A" experiment-id="hero-test">
      <div data-variant="A">
        <h1>Welcome to our amazing product!</h1>
        <button>Get Started</button>
      </div>
      <div data-variant="B">
        <h1>Discover something incredible!</h1>
        <button>Try Now</button>
      </div>
    </gx-experiment-wrapper>
  </body>
</html>
```

## 📚 API Reference

### Core Functions

#### `getVariant(config: ExperimentConfig): string`

Determines which variant a user should see based on the experiment configuration.

```typescript
const variant = getVariant({
  experimentId: 'my-experiment',
  variants: [
    { name: 'control', weight: 0.5 },
    { name: 'treatment', weight: 0.5 },
  ],
  weights: [0.5, 0.5], // Optional: override individual variant weights
  description: 'Testing new button color',
  targeting: {
    trafficPercentage: 0.1, // 10% of traffic
    deviceType: 'mobile',
    country: 'US',
  },
});
```

### React Components

#### `GxExperimentWrapper`

A React wrapper component that handles variant assignment and tracking.

```tsx
interface ExperimentWrapperProps {
  config: ExperimentConfig;
  trackingEndpoint?: string;
  gaTracking?: boolean;
  autoTrack?: boolean;
  fallbackVariant?: string;
  debug?: boolean;
  loading?: boolean;
  onTrack?: (event: string, data: TrackingEvent) => void;
  onVariantAssigned?: (variant: string, experimentId: string) => void;
  onError?: (error: string, experimentId?: string) => void;
  children: React.ReactNode;
}
```

### Vue Components

#### `GxExperimentWrapper`

A Vue wrapper component with similar functionality to the React version.

```vue
<GxExperimentWrapper :variant="variant" experiment-id="my-experiment" :ga-tracking="true" :debug="true" @track="handleTrack" @variant-assigned="handleVariantAssigned" @error="handleError">
  <!-- Your variants here -->
</GxExperimentWrapper>
```

### Web Components

#### `<gx-experiment-wrapper>`

A custom HTML element that works in any framework or vanilla JavaScript.

```html
<gx-experiment-wrapper variant="A" experiment-id="my-experiment" ga-tracking="true" debug="true">
  <div data-variant="A">Variant A</div>
  <div data-variant="B">Variant B</div>
</gx-experiment-wrapper>
```

### TypeScript Interfaces

#### `ExperimentConfig`

```typescript
interface ExperimentConfig {
  experimentId: string;
  variants: Variant[];
  weights?: number[];
  description?: string;
  targeting?: TargetingConfig;
  metadata?: Record<string, any>;
}

interface Variant {
  name: string;
  weight?: number;
  component?: any;
  metadata?: Record<string, any>;
}

interface TargetingConfig {
  trafficPercentage?: number;
  deviceType?: 'mobile' | 'desktop' | 'tablet';
  country?: string;
  userSegment?: string;
  customRules?: Record<string, any>;
}
```

#### `TrackingEvent`

```typescript
interface TrackingEvent {
  event: string;
  experimentId: string;
  variant: string;
  timestamp: number;
  sessionId?: string;
  userId?: string;
  customData?: Record<string, any>;
}
```

## 🎯 Advanced Usage

### Custom Targeting

```typescript
const variant = getVariant({
  experimentId: 'premium-feature-test',
  variants: [{ name: 'control' }, { name: 'premium' }],
  targeting: {
    trafficPercentage: 0.2, // 20% of users
    deviceType: 'desktop',
    country: 'US',
    userSegment: 'premium',
    customRules: {
      userAge: { min: 25, max: 65 },
      subscriptionTier: ['pro', 'enterprise'],
    },
  },
});
```

### Analytics Integration

```tsx
<GxExperimentWrapper
  config={experimentConfig}
  gaTracking={true}
  trackingEndpoint="https://api.yourapp.com/analytics"
  onTrack={(event, data) => {
    // Custom analytics
    analytics.track(event, data);

    // Google Analytics
    gtag('event', event, {
      experiment_id: data.experimentId,
      variant: data.variant,
      custom_parameter: data.customData,
    });
  }}
>
  {/* Your variants */}
</GxExperimentWrapper>
```

### Debug Mode

```tsx
<GxExperimentWrapper
  config={experimentConfig}
  debug={true}
  onVariantAssigned={(variant, experimentId) => {
    console.log(`User assigned to variant ${variant} in experiment ${experimentId}`);
  }}
  onError={(error, experimentId) => {
    console.error(`Experiment error: ${error}`, experimentId);
  }}
>
  {/* Your variants */}
</GxExperimentWrapper>
```

### Programmatic Control

```typescript
// Check if user is in a specific variant
const isVariant = (targetVariant: string) => {
  return getVariant(experimentConfig) === targetVariant;
};

// Reassign variant (useful for testing)
const reassignVariant = () => {
  localStorage.removeItem(`gx_experiment_${experimentId}`);
  // Next page load will reassign
};

// Get experiment status
const getExperimentStatus = () => {
  return {
    experimentId,
    variant: getVariant(experimentConfig),
    isInitialized: true,
    sessionId: getSessionId(),
    userId: getUserId(),
  };
};
```

## 🧪 Testing

### Unit Tests

```bash
npm test
```

### Integration Tests

```bash
npm run test:integration
```

### Demo Applications

```bash
# Start all demos
npm run demo

# React demo only
npm run demo:react

# Vue demo only
npm run demo:vue

# HTML demo
npm run demo:html
```

## 📊 Analytics & Tracking

### Built-in Events

- `experiment_viewed` - When a user sees an experiment
- `variant_assigned` - When a variant is assigned to a user
- `experiment_error` - When an error occurs

### Custom Events

```tsx
<GxExperimentWrapper
  config={experimentConfig}
  onTrack={(event, data) => {
    // Track custom events
    if (event === 'button_clicked') {
      analytics.track('Button Clicked', {
        experiment: data.experimentId,
        variant: data.variant,
        button_text: data.customData?.buttonText,
      });
    }
  }}
>
  <div data-variant="A">
    <button onClick={() => track('button_clicked', { buttonText: 'Get Started' })}>Get Started</button>
  </div>
</GxExperimentWrapper>
```

## 🔧 Configuration

### Environment Variables

```bash
# Optional: Custom tracking endpoint
GX_TRACKING_ENDPOINT=https://api.yourapp.com/analytics

# Optional: Enable debug mode
GX_DEBUG=true

# Optional: Default experiment configuration
GX_DEFAULT_CONFIG=./experiments.json
```

### Build Configuration

The library supports multiple build targets:

- **ES Modules** (`dist/index.mjs`) - For modern bundlers
- **CommonJS** (`dist/index.js`) - For Node.js and older bundlers
- **TypeScript** (`dist/index.d.ts`) - For type definitions

### Development Setup

```bash
# Clone the repository
git clone https://github.com/ducky0209/gemx-package.git
cd gemx-package

# Install dependencies
npm install

# Build the library
npm run build

# Run tests
npm test

# Start development server
npm run demo:react
```

### Project Structure

```
src/
├── adapters/          # Framework-specific adapters
│   ├── react/        # React components
│   └── vue/          # Vue components
├── components/        # Web components
├── core/             # Core A/B testing logic
├── types/            # TypeScript type definitions
├── utils/            # Utility functions
└── tracking/         # Analytics and tracking
```

## 🆘 Support

- 📖 [Documentation](https://github.com/ducky0209/gemx-package#readme)
- 🐛 [Bug Reports](https://github.com/ducky0209/gemx-package/issues)
- 💬 [Discussions](https://github.com/ducky0209/gemx-package/discussions)
- 📧 [Email Support](mailto:support@gemx.dev)

---

**Made with ❤️ by the GemX team**