> For the complete documentation index, see [llms.txt](https://kluvos.gitbook.io/kluvos-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kluvos.gitbook.io/kluvos-docs/integrate-kluvos-with-a-shopify-hydrogen-store.md).

# Integrate Kluvos with a Shopify Hydrogen Store

This guide explains how to integrate Kluvos tracking scripts into your Shopify Hydrogen store. Follow these steps to enable tracking of customer events.

#### Step 1: Add the Kluvos Script to your Header

Include the following script in your application's root component (`root.jsx`), within the `<head>` section:

```javascript
import { Script } from '@shopify/hydrogen';

export default function App({ children, nonce }) {
  return (
    <html lang="en">
      <head>
        <Script
          async
          src="https://track.kluvos.com/scripts/v2/trxu?shop_id={yourshopID}"
          nonce={nonce}
        />
      </head>
      <body>
        {children}
      </body>
    </html>
  );
}
```

#### Step 2: Create the `KluvosOnsite.jsx` Component

Create a new file in `app/components/KluvosOnsite.jsx` with the provided helper functions and event tracking logic:

```javascript
// app/components/KluvosOnsite.jsx
import { useEffect, useCallback } from 'react';

function klvGetCookie(name) {
  const match = document.cookie.match(
    new RegExp('(?:^|; )' + name.replace(/([.*+?^${}()|[\]\\])/g, '\\$1') + '=([^;]*)')
  );
  return match ? decodeURIComponent(match[1]) : null;
}

async function klvKlaviyoExchangeId() {
  const raw = await klvGetCookie('__kla_id');
  if (raw) {
    try {
      return JSON.parse(atob(raw)).$exchange_id;
    } catch {}
  }
  return null;
}

function klvGetKxTokenFromUrl() {
  try {
    const params = new URLSearchParams(window.location.search);
    return params.get('_kx');
  } catch {
    return null;
  }
}

async function klvGetKxToken() {
  const urlToken = klvGetKxTokenFromUrl();
  if (urlToken) return urlToken;
  try {
    return await klvKlaviyoExchangeId();
  } catch {
    return null;
  }
}


async function klvGetMetadata() {
  return {
    fbc:  klvGetCookie('_fbc'),
    fbp:  klvGetCookie('_fbp'),
    lt_cookie: klvGetCookie('_kpixel_lt'),
    kx:   await klvGetKxToken(),
  };
}
const KLUVOS_TRACK_URL = 'https://track.kluvos.com';

const KLV_ENDPOINTS = {
  add_to_cart: 'shopify_customer_events/add_to_carts',
  product_view: 'shopify_customer_events/product_views',
};

export function sendKluvosEvent(eventType, payload) {
  const path = KLV_ENDPOINTS[eventType];
  if (!path) {
    console.error(`sendKluvosEvent: unknown event type "${eventType}"`);
    return;
  }

  const url = `${KLUVOS_TRACK_URL}/api/v1/${path}`;
  const body = JSON.stringify(payload);

  fetch(url, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body,
    keepalive: true,
  }).catch((err) => console.warn('sendEvent failed:', err));
}

export async function kluvosProductView(product) {
  if (typeof window === 'undefined') return;

  const origin = window.location.origin;
  const session_cookie = await klvGetCookie('_kpixel_s');
  const metadata = await klvGetMetadata();
  const time_utc = new Date().toISOString();
  const client_event_id = `H-${crypto.randomUUID()}`;


  const payload = {
    product_view: {
      event_name: 'product_viewed',
      session_cookie,
      product_data: {
        url: `${origin}/products/${product?.handle}`,
        name: product?.title,
        brand: product?.vendor,
        price: product?.selectedOrFirstAvailableVariant?.price?.amount,
        currency: product?.selectedOrFirstAvailableVariant?.price?.currencyCode,
        type: product?.productType,
        sku: product?.selectedOrFirstAvailableVariant?.sku,
        variant_title: product?.selectedOrFirstAvailableVariant?.title,
        image_url: product?.selectedOrFirstAvailableVariant?.image?.url || '',
        categories: product?.productType ? [product?.productType] : [],
        product_id: product?.id?.substring(product?.id?.lastIndexOf('/') + 1),
      },
      time_utc,
      origin,
      client_event_id,
      metadata,
    },
  };

  sendKluvosEvent('product_view', payload);
}

export async function kluvosAddToCart(selectedVariant) {
  if (typeof window === 'undefined') return;

  const origin = window.location.origin;
  const session_cookie = await klvGetCookie('_kpixel_s');
  const cart_token = await klvGetCookie('cart');
  const metadata = await klvGetMetadata();
  const time_utc = new Date().toISOString();
  const client_event_id = `H-${crypto.randomUUID()}`;

  const payload = {
    origin,
    session_cookie,
    currency: selectedVariant?.price?.currencyCode,
    item_count: 1,
    items: [{
      id: selectedVariant?.id?.substring(selectedVariant?.id?.lastIndexOf('/') + 1),
      title: selectedVariant?.product?.title,
      image_src: selectedVariant?.image?.url,
      price: selectedVariant?.price?.amount,
      currency: selectedVariant?.price?.currencyCode,
      handle: selectedVariant?.product?.handle,
      sku: selectedVariant?.sku,
      quantity: 1,
      url: `${origin}/products/${selectedVariant?.product?.handle}`,

    }],
    cart_token,
    total_price: selectedVariant?.price?.amount,
    time_utc,
    action_type: 'add',
    client_event_id,
    metadata,
  };

  sendKluvosEvent('add_to_cart', payload);
}
```

#### Step 3: Tracking Product Views

In your product page component (`app/routes/products.$handle.jsx`), use the following example to track product views:

```javascript
import { useEffect } from 'react';
import { kluvosProductView } from '~/components/KluvosOnsite';

export default function Product({ product, selectedVariant }) {
  // Your existing product logic
  
  useEffect(() => {
    kluvosProductView(product);
  }, [product]);


}
```

#### Step 4: Tracking Add to Cart Events

To track add-to-cart actions, integrate your `kluvosAtcFire` function into your AddToCart button as follows:

```javascript
import { kluvosAddToCart } from '~/components/KluvosOnsite';

const kluvosAtcFire = () => {
  kluvosAddToCart(selectedVariant);
};


// Example AddToCartButton component usage
<AddToCartButton
  disabled={!selectedVariant || !selectedVariant.availableForSale}
  onClick={() => {
    open('cart');
    //place add to cart function here
    kluvosAtcFire()

  }}
  lines={
    selectedVariant
      ? [
          {
            merchandiseId: selectedVariant.id,
            quantity: 1,
            selectedVariant,
          },
        ]
      : []
  }
>
  {selectedVariant?.availableForSale ? 'Add to cart' : 'Sold out'}
</AddToCartButton>
```
