# Web Experiments

Web experiments enable A/B testing by dynamically modifying web page content based on feature flag variants. They automatically apply visual transformations to elements without code changes.

## Package Information

Import from PostHog instance:

```typescript
const experiments = posthog.experiments;
```

## Capabilities

### Get and Evaluate Web Experiments

Fetches web experiments from the server and evaluates which ones to apply based on current feature flag values, URL matching, and display conditions.

```typescript { .api }
/**
 * Get web experiments and evaluate display logic
 * @param forceReload - Force reload from server, bypassing cache
 */
function getWebExperimentsAndEvaluateDisplayLogic(forceReload?: boolean): void;
```

**Usage Example:**

```typescript
import posthog from 'posthog-js';

// Automatically load and apply experiments
posthog.experiments.getWebExperimentsAndEvaluateDisplayLogic();

// Force reload from server
posthog.experiments.getWebExperimentsAndEvaluateDisplayLogic(true);
```

### Get Web Experiments

Fetches web experiments with a callback, optionally enabling preview mode.

```typescript { .api }
/**
 * Get web experiments with callback
 * @param callback - Called with array of web experiments
 * @param forceReload - Force reload from server
 * @param previewing - Enable preview mode (for testing)
 */
function getWebExperiments(
  callback: WebExperimentsCallback,
  forceReload: boolean,
  previewing?: boolean
): void;

type WebExperimentsCallback = (webExperiments: WebExperiment[]) => void;
```

**Usage Example:**

```typescript
posthog.experiments.getWebExperiments(
  (experiments) => {
    console.log('Loaded experiments:', experiments);
    experiments.forEach(exp => {
      console.log(`Experiment ${exp.name}: ${exp.variants}`);
    });
  },
  false // Don't force reload
);
```

### Preview Web Experiment

Activates web experiment preview mode using query parameters `__experiment_id` and `__experiment_variant` in the URL.

```typescript { .api }
/**
 * Preview a web experiment from URL parameters
 * Looks for __experiment_id and __experiment_variant query params
 */
function previewWebExperiment(): void;
```

**Usage Example:**

```typescript
// URL: https://example.com?__experiment_id=123&__experiment_variant=test
posthog.experiments.previewWebExperiment();
// Applies the "test" variant of experiment 123
```

### Load If Enabled

Loads experiments if enabled in configuration. Called automatically during PostHog initialization.

```typescript { .api }
/**
 * Load experiments if enabled in config
 * Typically called internally during initialization
 */
function loadIfEnabled(): void;
```

## Configuration

Web experiments are controlled via PostHog configuration:

```typescript
posthog.init('YOUR_PROJECT_API_KEY', {
  api_host: 'https://us.i.posthog.com',
  // Web experiments are disabled by default (beta feature)
  disable_web_experiments: false, // Set to false to enable
});
```

## Types

### WebExperiment

Main web experiment interface.

```typescript { .api }
interface WebExperiment {
  /** Unique experiment ID */
  id: number;
  /** Human-readable experiment name */
  name: string;
  /** Optional feature flag key controlling this experiment */
  feature_flag_key?: string;
  /** Map of variant names to variant configurations */
  variants: Record<string, WebExperimentVariant>;
}
```

### WebExperimentVariant

Defines a single variant within an experiment.

```typescript { .api }
interface WebExperimentVariant {
  /** Display conditions for this variant */
  conditions?: WebExperimentConditions;
  /** Variant name (matches feature flag variant value) */
  variant_name: string;
  /** List of transformations to apply */
  transforms: WebExperimentTransform[];
}
```

### WebExperimentConditions

Conditions that determine when a variant is applied.

```typescript { .api }
interface WebExperimentConditions {
  /** URL matching configuration */
  url?: string;
  /** How to match the URL */
  urlMatchType?: WebExperimentUrlMatchType;
  /** UTM parameter matching */
  utm?: {
    utm_source?: string;
    utm_medium?: string;
    utm_campaign?: string;
    utm_term?: string;
  };
}

type WebExperimentUrlMatchType =
  | 'regex'         // Regular expression match
  | 'not_regex'     // Inverse regex match
  | 'exact'         // Exact URL match
  | 'is_not'        // URL is not this value
  | 'icontains'     // URL contains substring (case-insensitive)
  | 'not_icontains' // URL does not contain substring
  ;
```

### WebExperimentTransform

Defines a transformation to apply to page elements.

```typescript { .api }
interface WebExperimentTransform {
  /** CSS selector to target elements */
  selector?: string;
  /** HTML attributes to set/modify */
  attributes?: Array<{ name: string; value: string }>;
  /** Text content to replace */
  text?: string;
  /** HTML content to replace */
  html?: string;
  /** Image URL to replace */
  imgUrl?: string;
  /** CSS styles to apply */
  css?: string;
}
```

**Transform Examples:**

```typescript
// Change button text
{
  selector: '.cta-button',
  text: 'Buy Now - 20% Off!'
}

// Modify image source
{
  selector: '#hero-image',
  imgUrl: 'https://example.com/new-hero.jpg'
}

// Apply custom CSS
{
  selector: '.pricing-card',
  css: 'background-color: #ff6b6b; border: 2px solid #000;'
}

// Change multiple attributes
{
  selector: 'a.signup-link',
  attributes: [
    { name: 'href', value: '/special-offer' },
    { name: 'class', value: 'btn btn-primary' }
  ]
}

// Replace HTML content
{
  selector: '.announcement',
  html: '<strong>Limited Time:</strong> Get 50% off!'
}
```

## How Web Experiments Work

1. **Feature Flag Integration**: Web experiments are tied to feature flag variants. When a user is assigned to a variant, the experiment's transforms are applied.

2. **Conditions Evaluation**: Before applying transforms, PostHog checks:
   - URL matching (if specified)
   - UTM parameters (if specified)
   - Feature flag evaluation result

3. **Transform Application**: If conditions are met, transforms are applied to matching elements using DOM manipulation.

4. **Preview Mode**: Use query parameters to preview specific variants without feature flag evaluation.

## Best Practices

1. **Test Selectors**: Ensure CSS selectors are specific enough to target the right elements without side effects.

2. **Performance**: Limit the number of transforms per experiment to minimize DOM manipulation overhead.

3. **Fallbacks**: Design experiments so the original experience is acceptable if transforms fail to apply.

4. **Feature Flags**: Always tie experiments to feature flags for proper variant assignment and analytics.

5. **Preview Before Launch**: Use preview mode to verify transforms work correctly before enabling for users.

## Related

- [Feature Flags](./feature-flags.md) - Control experiment variants
- [Events](./events.md) - Track experiment interactions
- [Initialization](./initialization.md) - Configuration options
