# window\.shoplift

The `window.shoplift` object is the entry point for the Shoplift JavaScript API. It's automatically set up on every page of your Shopify store and exposes three methods for interacting with A/B tests.

### Availability

The object is available after Shoplift's script has loaded and initialized. It is attached to the global `window` scope — no imports or module resolution is required.

```javascript
// The object exists on window after script initialization
typeof window.shoplift // 'object' when loaded, 'undefined' before

// Always guard access
if (window.shoplift) {
  // Safe to use
}
```

### Object Shape

```typescript
interface ShopliftPublic {
  /**
   * Check if the current visitor is assigned to a specific hypothesis.
   * Returns true if the visitor is assigned to the given hypothesis,
   * false otherwise (control, different variant, test inactive, etc.).
   */
  isHypothesisActive(hypothesisId: string): Promise<boolean>;

  /**
   * Manually set visitor analytics consent.
   * Only needed for custom consent management platforms.
   */
  setAnalyticsConsent(consent: boolean): Promise<void>;

  /**
   * Retrieve visitor information and test assignments.
   * Synchronous — returns data immediately.
   */
  getVisitorData(): ExternalVisitorData;
}
```

### Methods

<table><thead><tr><th width="204.76171875">Method</th><th>Purpose</th><th>Returns</th><th>Async</th></tr></thead><tbody><tr><td><code>isHypothesisActive()</code></td><td>Check if visitor is assigned to a specific test variant</td><td><code>Promise&#x3C;boolean></code></td><td>Yes</td></tr><tr><td><code>setAnalyticsConsent()</code></td><td>Sets the visitor's analytics consent state</td><td><code>Promise&#x3C;void></code></td><td>Yes</td></tr><tr><td><code>getVisitorData()</code></td><td>Returns visitor info and all test assignments</td><td><code>ExternalVisitorData</code></td><td>No</td></tr></tbody></table>

### Loading Behavior

Shoplift manages its script in your store's theme and loads with the following characteristics:

* **Automatic management** — Shoplift installs and maintains the script. You never need to add it manually.
* **Early loading** — The script loads before most other third-party scripts to reduce flicker when applying variant changes.
* **Automatic updates** — When Shoplift releases improvements, the script updates without any action on your part.

### Waiting for the Object

If your code runs before Shoplift's script has loaded, `window.shoplift` will be `undefined`. Use one of these patterns to wait:

#### Polling

```javascript
function onShopliftReady(callback, maxAttempts = 50) {
  let attempts = 0;

  function check() {
    if (window.shoplift) {
      callback(window.shoplift);
    } else if (attempts < maxAttempts) {
      attempts++;
      setTimeout(check, 100);
    } else {
      console.warn('Shoplift: script did not load.');
    }
  }

  check();
}

onShopliftReady(async (shoplift) => {
  const isActive = await shoplift.isHypothesisActive('hypothesis-id');
  // ...
});
```

#### Inline Guard

For one-off checks where you don't need to wait:

```javascript
if (window.shoplift) {
  const data = window.shoplift.getVisitorData();
}
```

### Error Handling

`isHypothesisActive` returns a Promise that may reject if visitor assignment fails (e.g., a network error during splitting). Wrap calls in try/catch to fall back gracefully:

```javascript
try {
  const isVariant = await window.shoplift.isHypothesisActive('hypothesis-id');
  // Apply variant
} catch (error) {
  console.error('Shoplift error:', error);
  // Fall back to control experience
}
```

`setAnalyticsConsent` handles errors internally and will not reject in practice, but wrapping it in try/catch is still safe defensive coding.

The synchronous `getVisitorData()` method will not throw, but may return `{ visitor: null, visitorTests: [] }` if the visitor hasn't been created yet or if Shoplift could not fully initialize (e.g., merchant preview mode or an initialization error). Invalid test assignments are automatically filtered out before the data is returned.

### Browser Compatibility

The Shoplift script works in all modern browsers (Chrome, Firefox, Safari, Edge). It uses Promises, so environments must support ES6+ or have a polyfill loaded.

### TypeScript

Add these declarations to your project to get type-checking:

```typescript
interface ShopliftPublic {
  isHypothesisActive(hypothesisId: string): Promise<boolean>;
  setAnalyticsConsent(consent: boolean): Promise<void>;
  getVisitorData(): ExternalVisitorData;
}

interface ExternalVisitorData {
  visitor: Visitor | null;
  visitorTests: ExternalTestRelation[];
}

interface Visitor {
  id: string;                        // Unique visitor ID (UUID)
  createdAt: Date;                   // When visitor first arrived
  shopifyAnalyticsId: string | null; // Shopify's analytics ID (if available)
  device: 'desktop' | 'mobile';     // Device type
  country: string | null;           // Visitor country (if available)
  utmSource: string;                // UTM source parameter
  utmMedium: string;                // UTM medium parameter
  utmCampaign: string;              // UTM campaign parameter
  utmContent: string;               // UTM content parameter
  referrer: string;                 // Referring URL
}

interface ExternalTestRelation {
  createdAt: Date;                  // When assigned to test
  testId: string;                   // Test identifier
  hypothesisId: string | null;      // Hypothesis ID (null if excluded from test)
  isThemeTest: boolean;             // Whether this is a theme test
  themeId?: number;                 // Theme ID (for theme tests only)
  isInvalid?: boolean;              // Whether assignment has been invalidated
}

declare global {
  interface Window {
    shoplift?: ShopliftPublic;
  }
}
```
