npm package: @solute-ai/client-sdk
Description: Browser SDK for Solute experimentation platform
Latest version: 1.1.0

# Client SDK

Browser SDK for integrating Solute experiments into web applications.

## Features

- Consistent user bucketing (hash-based)
- Treatment script injection from CDN
- Real user monitoring (exposures, conversions, errors)
- Lightweight and performant

## Quick start (landing page)

The easiest way to integrate is to let the SDK **discover experiments for you** and populate the
`solute-experiments` meta tag automatically.

### Via CDN (no bundler)

```html
<!-- 1) Load the SDK bundle -->
<script src="https://static.example.com/solute-sdk.min.js"></script>

<!-- 2) Bootstrap Solute -->
<script>
  document.addEventListener('DOMContentLoaded', function () {
    SoluteSDK.bootstrap({
      apiUrl: 'https://your-api.execute-api.us-west-2.amazonaws.com/dev', // Tickets API base URL
      apiKey: '<optional-x-api-key>',                                     // omit if not needed
      siteId: 'your-tenant-id',                                           // e.g. 'demo-site'
      cloudFrontDomain: 'your-snippets-domain.cloudfront.net',            // from Orchestrator stack
      debug: true,
    }).catch(function (err) {
      console.error('[Solute] bootstrap error', err);
    });
  });
</script>
```

This will:

- Call `GET /tickets?tenant_id=<siteId>` on your Tickets API.
- Filter for `state === "RUNNING"`.
- Write the mapped experiments into:

```html
<meta name="solute-experiments" content='[{"id":"...","flagKey":"exp_...","split":{"treatment":0.5}}]'>
```

- Instantiate `SoluteSDK` and call `init()` so snippets are loaded from
  `https://<cloudFrontDomain>/<experiment-id>/treatment.js`.

## Installation (npm)

```bash
npm install @solute-ai/client-sdk
```

```javascript
import { bootstrapSolute } from '@solute-ai/client-sdk';

await bootstrapSolute({
  apiUrl: 'https://your-api.execute-api.us-west-2.amazonaws.com/dev',
  apiKey: process.env.SOLUTE_API_KEY,                 // optional
  siteId: 'your-tenant-id',
  cloudFrontDomain: 'your-snippets-domain.cloudfront.net',
  debug: true,
});
```

## Usage

### Track Conversions

```javascript
sdk.trackConversion('signup_completed');
sdk.trackConversion('purchase', 99.99);
```

### Identify Users

```javascript
sdk.identify('user-123', {
  email: 'user@example.com',
  plan: 'pro'
});
```

### Server-side Experiment Injection (advanced)

If you prefer to inject configuration server-side (e.g. from your own backend or admin UI), you can
skip `bootstrapSolute` and write the `solute-experiments` meta tag yourself using the same format:

```html
<meta name="solute-experiments" content='[
  {
    "id": "exp-123",
    "flagKey": "exp_exp-123",
    "split": { "treatment": 0.1 }
  }
]'>
```

Then call `new SoluteSDK({ siteId, cloudFrontDomain }).init()` once on page load.

### Runtime behavior guarantees

- **Deterministic bucketing** – user IDs persist via `localStorage` (with in-memory fallback) and a stable hash assigns each `{user, experiment}` pair to control or treatment.
- **One-time snippet injection** – treatment JavaScript is fetched from CloudFront/S3 once per experiment and cached client-side.
- **Real User Monitoring (RUM)** – exposures for both control and treatment variants plus conversions/errors are sent to PostHog whenever it’s present on the page (and always logged to the console for debugging). Conversion events fan out to every active experiment context, so multi-experiment pages keep attribution intact.
- **Graceful degradation** – when PostHog or Web Storage APIs are unavailable the SDK continues operating with in-memory fallbacks and console logging.

## Local Development

```bash
npm run build
npm run test
```

## Build Output

- `dist/solute-sdk.js` - UMD build
- `dist/solute-sdk.min.js` - Minified UMD
- `dist/solute-sdk.esm.js` - ES module build