> ## Documentation Index
> Fetch the complete documentation index at: https://docs.taap.it/llms.txt
> Use this file to discover all available pages before exploring further.

# Client-side Integration

> Track conversions directly from your frontend using the NPM package or script tag

import { Steps, Step } from "fumadocs-ui/components/steps";

Track leads and sales directly from the browser. This method is simple to implement but can be blocked by ad blockers.

<Warning>
  Client-side tracking can be **blocked by ad blockers**. For maximum
  reliability, we strongly recommend [Server-side
  Integration](/conversions/manual/server-side) instead.
</Warning>

## Prerequisites

<Warning>
  **Important**: For conversion tracking to work, users must arrive on your
  website via a **Taapit deeplink**. This is how the tracking ID (`ta_tid`) is
  generated and passed to your site.
</Warning>

Before you start:

1. **Create a Taapit deeplink** pointing to your website or landing page
2. **Enable conversion tracking** on your link:
   * Go to your link settings in the Taapit dashboard
   * Enable **Conversion Tracking**

Then, configure your Taapit workspace:

<Steps>
  <Step title="Go to Conversion settings">
    1. In your Taapit dashboard, go to [Settings →
       Conversion](https://taap.it/dashboard/settings/conversion) 2. In the
       dropdown, select **Manual Client-side Integration**
  </Step>

  <Step title="Add your allowed hostnames">
    1. In the **Allowed Hostnames** section, add your website domains (e.g.,
       `example.com`, `www.example.com`) 2. Click **Save**

    <Warning>
      The SDK will only work on domains listed in your allowed hostnames. Don't
      forget to add both `www` and non-`www` versions if needed.
    </Warning>
  </Step>

  <Step title="Get your Publishable Key">
    1. Copy your **Publishable Key** (starts with `taapit_pk_`) 2. You'll use
       this key in the next steps

    <Info>
      If you don't have a publishable key yet, click **Generate Key** to create
      one.
    </Info>
  </Step>
</Steps>

## Installation

Choose your preferred method:

<Tabs>
  <Tab title="NPM Package (React/Next.js)">
    <Steps>
      <Step title="Install the SDK">
        ```bash theme={null}
        npm install taapit-sdk
        ```
      </Step>

      <Step title="Add the Analytics component">
        Add the `Analytics` component to your root layout to automatically capture the `ta_tid`:

        ```tsx app/layout.tsx theme={null}
        import { Analytics } from 'taapit-sdk/react';

        export default function RootLayout({ children }) {
          return (
            <html>
              <body>
                {children}
                <Analytics publishableKey="taapit_pk_xxx" />
              </body>
            </html>
          );
        }
        ```

        <Info>
          Get your publishable key from the [Taapit Dashboard](https://taap.it/dashboard/settings/analytics).
        </Info>
      </Step>
    </Steps>
  </Tab>

  <Tab title="Script Tag (No Build Step)">
    Add this script to your HTML `<head>` or before `</body>`:

    ```html theme={null}
    <script
      src="https://taap.it/api/sdk"
      data-publishable-key="taapit_pk_xxx"
    ></script>
    ```

    The script automatically:

    * Captures the `ta_tid` from the URL when users arrive
    * Stores it in a cookie for 365 days
    * Exposes the global `taapit` object

    **Alternative methods:**

    ```html theme={null}
    <!-- Via URL parameter -->
    <script src="https://taap.it/api/sdk?key=taapit_pk_xxx"></script>

    <!-- Or configure programmatically -->
    <script src="https://taap.it/api/sdk"></script>
    <script>
      taapit.configure({ publishableKey: "taapit_pk_xxx" });
    </script>
    ```
  </Tab>
</Tabs>

## Track a Lead

A **lead** is a potential customer who shows interest (sign-up, form submission, trial start).

<Info>
  **`trackingId` for leads**: The `trackingId` is **always required** for lead
  events. It is automatically detected from the `ta_tid` cookie set when the
  user clicked a Taapit link.
</Info>

<Tabs>
  <Tab title="NPM Package">
    ```tsx components/signup-form.tsx theme={null}
    'use client';

    import { useTaapitAnalytics } from 'taapit-sdk/react';

    export function SignUpForm() {
      const { trackLead, isReady, trackingId } = useTaapitAnalytics();

    const handleSubmit = async (formData: FormData) => {
    const email = formData.get('email') as string;
    const name = formData.get('name') as string;

        // Create user in your system
        const user = await createUser({ email, name });

        // Track the lead with Taapit
        trackLead({
          customer: {
            externalId: user.id,      // Required: your user ID
            email: user.email,
            firstname: user.firstName,
            lastname: user.lastName,
          },
          metadata: {
            source: 'signup-form',
            plan: 'free-trial',
          },
        });

    };

    return (

    <form action={handleSubmit}>
      <input name="name" placeholder="Name" required />
      <input name="email" type="email" placeholder="Email" required />
      <button type="submit">Start Free Trial</button>
    </form>
    ); }

    ```

    ### Direct import (alternative)

    ```tsx theme={null}
    import { taapit } from 'taapit-sdk/react';

    export function SignUpButton() {
      const handleClick = async () => {
        const user = await signUp();
        taapit.trackLead({
          customer: { externalId: user.id, email: user.email },
        });
      };

      return <button onClick={handleClick}>Sign Up</button>;
    }
    ```
  </Tab>

  <Tab title="Script Tag">
    ```html theme={null}
    <script>
      document.getElementById('signup-form').addEventListener('submit', async (e) => {
        e.preventDefault();
        
        const formData = new FormData(e.target);
        
        // Create user via your API
        const response = await fetch('/api/signup', {
          method: 'POST',
          body: formData,
        });
        const user = await response.json();
        
        // Track the lead
        taapit.trackLead({
          customer: {
            externalId: user.id,
            email: formData.get('email'),
            firstname: formData.get('name').split(' ')[0],
            lastname: formData.get('name').split(' ').slice(1).join(' '),
          },
        });
        
        window.location.href = '/dashboard';
      });
    </script>
    ```
  </Tab>
</Tabs>

## Track a Sale

A **sale** is a completed transaction (purchase, subscription, payment).

<Info>
  **`trackingId` for sales**: If the customer was already tracked via a **lead
  event**, the `trackingId` is optional. You only need the `customerExternalId`
  to link the sale to the existing customer. If this is a **new customer** (no
  prior lead), the user must have a valid `ta_tid` cookie (set by clicking a
  Taapit link).
</Info>

<Tabs>
  <Tab title="NPM Package">
    ```tsx components/checkout.tsx theme={null}
    'use client';

    import { useTaapitAnalytics } from 'taapit-sdk/react';

    export function CheckoutButton({ cart, user }) {
      const { trackSale } = useTaapitAnalytics();

    const handlePurchase = async () => {
    // Process payment
    const order = await processPayment(cart);

        // Track the sale with Taapit
        trackSale({
          customer: {
            externalId: user.id,
            email: user.email,
          },
          amount: cart.total,  // e.g., 49.99 (NOT cents)
          currency: 'eur',     // ISO 4217 code
          metadata: {
            orderId: order.id,
            items: cart.items.length,
          },
        });

        router.push(`/order/${order.id}`);

    };

    return (

    <button onClick={handlePurchase}>Complete Purchase - €{cart.total}</button>
    ); }

    ```
  </Tab>

  <Tab title="Script Tag">
    ```html theme={null}
    <script>
      document.getElementById('checkout-btn').addEventListener('click', async () => {
        // Process payment via your API
        const response = await fetch('/api/checkout', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ cartId: 'cart_123' }),
        });
        const order = await response.json();

        // Track the sale
        taapit.trackSale({
          customer: {
            externalId: order.userId,
            email: order.customerEmail,
          },
          amount: order.total,
          currency: order.currency,
          metadata: { orderId: order.id },
        });

        window.location.href = `/order/${order.id}`;
      });
    </script>
    ```
  </Tab>
</Tabs>

<Warning>
  The `amount` must be in **currency units**, not cents. - ✅ `amount: 29.99`
  for €29.99 - ❌ `amount: 2999` (this would be €2999)
</Warning>

## Available Methods

```javascript theme={null}
// Get the current tracking ID
const trackingId = taapit.getTrackingId();

// Track a lead (trackingId is ALWAYS required - auto-detected from cookie)
taapit.trackLead({
  customer: {
    externalId: 'user_123',    // Required
    email: 'john@example.com',
    firstname: 'John',
    lastname: 'Doe',
    phoneNumber: '+33612345678',
    avatarUrl: 'https://example.com/avatar.jpg',
  },
  metadata: { ... },  // Optional custom data
});

// Track a sale
// trackingId is optional if customer was already tracked via a lead event
taapit.trackSale({
  customer: { externalId: 'user_123' },  // Required - links to existing customer
  amount: 99.99,      // Required
  currency: 'eur',    // Required (ISO 4217)
  metadata: { ... },
});
```

## Best Practices

### 1. Always track after confirmation

```typescript theme={null}
// ✅ Good - Track after action is confirmed
const user = await createUser(data);
taapit.trackLead({ customer: { externalId: user.id } });

// ❌ Bad - Track before confirmation
taapit.trackLead({ customer: { externalId: "pending" } });
const user = await createUser(data); // Might fail!
```

### 2. Handle missing tracking IDs gracefully

```typescript theme={null}
const trackingId = taapit.getTrackingId();

if (trackingId) {
  taapit.trackLead({...});
}
// Continue with your flow even without tracking
```

### 3. Use stable external IDs

```typescript theme={null}
// ✅ Good - Use your database ID
customer: {
  externalId: user.id;
}

// ❌ Bad - Don't use transient values
customer: {
  externalId: session.id;
}
```

## Limitations

* **Ad blockers** may block tracking requests
* **Browser restrictions** can prevent cookies from being set
* **Page close** before tracking completes loses the event

For critical conversions like sales, consider [Server-side Integration](/conversions/manual/server-side).

## Next Steps

<CardGroup cols={2}>
  <Card title="Server-side Integration" icon="server" href="/conversions/manual/server-side">
    More reliable tracking from your backend (recommended).
  </Card>

  <Card title="API Reference" icon="code" href="/conversions/api-reference">
    Full API documentation.
  </Card>
</CardGroup>
