---
title: Custom storefront installation
slug: custom-storefront-installation
docTags: 
createdAt: 2026-03-09T17:30:07.237Z
---

# Custom Storefront Installation

This guide covers adding Chord event tracking to custom-built storefronts, standalone websites, or commerce platforms other than Shopify.

## Prerequisites

Before starting, ensure you have the values listed in [Getting Started](#).

## Step 1: Install the Package

```shell
npm install @chordcommerce/analytics@1.21.3
# or
yarn add @chordcommerce/analytics@1.21.3
```

## Step 2: Initialize the Library

`@chordcommerce/analytics` is a browser-side library. It requires access to `window` and the DOM to load destination scripts, listen for events, and send tracking data. **It must not be initialized during server-side rendering (SSR).**

If your framework renders pages on the server (Next.js, Remix, Nuxt, Hydrogen, etc.), you must ensure Chord only initializes in the browser. Here are several approaches:

### Option A: React `useEffect` (Recommended for React frameworks)

`useEffect` only runs in the browser, never during SSR. This is the simplest and most idiomatic approach for React-based frameworks like Next.js and Hydrogen.

```tsx
'use client'

import { ChordAnalytics } from '@chordcommerce/analytics'
import { createContext, useContext, useEffect, useRef } from 'react'

const ChordContext = createContext<ChordAnalytics | null>(null)

export function ChordProvider({ children }: { children: React.ReactNode }) {
  const chordRef = useRef<ChordAnalytics | null>(null)

  useEffect(() => {
    if (!chordRef.current) {
      chordRef.current = new ChordAnalytics({
        cdpDomain: process.env.NEXT_PUBLIC_CHORD_DOMAIN,
        cdpWriteKey: process.env.NEXT_PUBLIC_CHORD_WRITE_KEY,
        formatters: {
          objects: {
            cart: (props) => { /* transform cart data */ },
            checkout: (props) => { /* transform checkout data */ },
            lineItem: (props) => { /* transform line item data */ },
            product: (props) => { /* transform product data */ },
          },
        },
        metadata: {
          i18n: { currency: 'USD', locale: 'en-US' },
          ownership: {
            omsId: process.env.NEXT_PUBLIC_CHORD_OMS_ID!,
            storeId: process.env.NEXT_PUBLIC_CHORD_STORE_ID!,
            tenantId: process.env.NEXT_PUBLIC_CHORD_TENANT_ID!,
          },
          platform: { name: 'Custom', type: 'web' },
          store: { domain: 'your-store-domain' },
        },
      })
    }
  }, [])

  return (
    <ChordContext.Provider value={chordRef.current}>
      {children}
    </ChordContext.Provider>
  )
}

export function useChord() {
  return useContext(ChordContext)
}
```

Then wrap your app in `<ChordProvider>` and use the `useChord()` hook in any component that needs to send tracking events.

### Option B: Next.js Dynamic Import with `ssr: false`

This prevents the Chord module from being imported on the server entirely. Useful when you want to isolate all Chord logic in a single component.

```tsx
import dynamic from 'next/dynamic'

const ChordProvider = dynamic(() => import('./ChordProvider'), { ssr: false })

export default function Layout({ children }) {
  return (
    <ChordProvider>
      {children}
    </ChordProvider>
  )
}
```

### Option C: `typeof window` Guard

The simplest approach for non-React frameworks or plain JavaScript. Check for the browser environment before initializing.

```typescript
import { ChordAnalytics } from '@chordcommerce/analytics'

if (typeof window !== 'undefined') {
  window.chord = new ChordAnalytics({
    cdpDomain: 'your-chord-domain',
    cdpWriteKey: 'your-chord-write-key',
    // ... rest of config
  })
}
```

:::hint{type="info"}
**Important:&#x20;**&#x54;he formatter examples above are illustrative. You must map your platform's specific data structures to the fields expected by the Chord tracking plan. See Configuration for detailed formatter documentation.
:::

## Step 3: Add Tracking Calls

Once initialized, use the SDK methods to track commerce events:

```typescript
// Page views
chord.page()

// Product interactions
chord.trackProductViewed({ cart, product: { product, quantity: 1 } })
chord.trackProductAdded({ cart, product: { product, quantity: 1 } })
chord.trackProductRemoved({ cart, lineitem })

// Cart
chord.trackCartViewed({ cart })

// Checkout
chord.trackCheckoutStarted({ checkout })
chord.trackPaymentInfoEntered({ checkoutId, step: 1, paymentMethod: 'credit_card' })

// Orders
chord.trackOrderCompleted({
  orderId: 'ORD-123',
  orderDate: '2026-03-09',
  currency: 'USD',
  revenue: 89.99,
  total: 99.99,
  products: [{ /* ... */ }],
})

// User identity
chord.identify(userId, { email: 'user@example.com' })
```

See [SDK API Reference](#) for the complete list of tracking methods and their parameters.

## Step 4: Add Environment Variables

```javascript
CHORD_DOMAIN=https://your-chord-domain
CHORD_WRITE_KEY=your-write-key
CHORD_OMS_ID=your-oms-id
CHORD_STORE_ID=your-store-id
CHORD_TENANT_ID=your-tenant-id
```

## TypeScript Support

The library supports generic type parameters for improved type safety:

```typescript
interface MyObjectTypes {
  Cart: MyCartType
  Checkout: MyCheckoutType
  LineItem: MyLineItemType
  Product: MyProductType
}

const chord = new ChordAnalytics<MyObjectTypes>(options)

// Now chord.trackProductViewed expects { product: MyProductType }
```

## Verifying the Installation

1. Set `debug: true` in your configuration options during development. This validates events against the tracking plan and logs warnings for missing or incorrect properties.
2. Check the browser console for Chord event logging.
3. Verify events appear in the Chord Live Events view.
