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

# Converge JS

> Connect your Website to Converge

## Installation instructions

<Steps>
  <Step title="Create a new Client Source in Converge">
    1. In Converge, click on **Create a new source**
    2. Pick *Client-side* from the modal
    3. Name your pixel: e.g. `{Storename} Storefront`
  </Step>

  <Step title="Install the Converge HTML snippet in your storefront">
    4. Click on your newly created Source and from the modal pick `HTML`, and copy that snippet.

    <Accordion icon="code" title="Code example">
      ```html theme={null}
      <script
        src="<https://static.runconverge.com/pixels/{YOUR_PUBLIC_TOKEN}.js>"
        async
      ></script>
      <script>
        window.cvg||(c=window.cvg=function(){c.process?c.process.apply(c,arguments):c.queue.push(arguments)},c.queue=[]);
        cvg({method:"track",eventName:"$page_load"});
      </script>
      ```
    </Accordion>

    5. Copy the HTML snippet and include it in the header of your website, right above the closing `</head>` tag.
  </Step>

  <Step title="Verify that the integration is working correctly">
    6. Check that your pixel is working correctly by generating some `$page_load` events by visiting the website and seeing that these events arrive in the Source Log.

    <Info>Set up a [Pixel Monitor](/sources/monitoring#pixel-monitor) to automatically verify your pixel stays installed.</Info>
  </Step>
</Steps>

<Warning>
  Implement Converge directly in your site's `<head>` whenever possible. We do not recommend using Google Tag Manager (GTM) or other tag managers as your permanent setup.

  GTM installation is technically possible - however, GTM can delay pixel loading, and ad blockers that block GTM containers can also silently block the Converge JS Pixel.
</Warning>

### Note for Single-page applications

<Warning>If you are using a single-page application, you should hook the `$page_load` tracking call into your router to re-fire the event. </Warning>

<Tabs>
  <Tab title="NextJS App Router">
    ```javascript theme={null}
      // app/ConvergePageView.jsx
      'use client'
      import { usePathname } from "next/navigation";
      import { useEffect } from "react";

      export default function ConvergePageView() {
        const pathname = usePathname();

        useEffect(() => {
          cvg({ method: "track", eventName: "$page_load" });
        }, [pathname])
        
        return null
      }

      // app/layout.js
      import ConvergePageView from "./ConvergePageView";

      export default function RootLayout({ children }) {
        return (
          <html lang="en">
            <body>
              <ConvergePageView /> 
              {children}
            </body>
          </html>
        )
      }
    ```
  </Tab>

  <Tab title="NextJS Page Router">
    ```javascript theme={null}
      import { useEffect } from "react";
      const MyApp = ({ Component, pageProps, router }) => {
        useEffect(() => {
          const handleRouteChange = (url) => {
            cvg({ method: "track", eventName: "$page_load" });
          };
          router.events.on("routeChangeComplete", handleRouteChange);
          return () => {
            router.events.off("routeChangeComplete", handleRouteChange);
          };
        }, []);
        return <Component {...pageProps} />;
      };
      export default MyApp;
    ```
  </Tab>
</Tabs>

***

## Cross-domain tracking

Converge supports cross-domain tracking through the methods below. We can stitch sessions across different domains and make sure that cookie information, first-party attribution, etc. will work correctly.

Note that you do **not** need to do anything for tracking across subdomains.
i.e. if the pixel snippet is installed on `myfirstdomain.com` and on `checkout.myfirstdomain.com`, the sessions should be stitched across both domains automatically.

If you want to stitch a session from `myfirstdomain.com` to `myotherdomain.com` then you will want to make sure to implement it as per the instructions below.

### How does cross-domain tracking work

Converge allows for cross-domain tracking through the `__cvg_uid` and `__cvg_sid` parameters and cookies.
If Converge recognizes the same `__cvg_uid` and `__cvg_sid` identifiers for pageviews on `myfirstdomain.com` and pageviews on `myotherdomain.com` then it will stitch those sessions under the same profile and session.

To stitch, we need to be able to pass the cookie between different websites as the cookie is only generated if the `__cvg_uid` and `__cvg_sid` are not set in the URL.
If there is a `__cvg_uid` set in the URL as a parameter, the cookie will be set to this value.

<Frame>
  ```mermaid actions={false} theme={null}
  flowchart TB
    id1("*User* visits **myfirstdomain.com** and gets assigned **__cvg_uid=1234** and **__cvg_sid=ABCD**") -. "Clicks on link myotherdomain.com/?__cvg_uid=1234&__cvg_sid=ABCD" .-> id2("*User* visits **myotherdomain.com** and Converge reads the id from the URL") ~~~ id3(["**Session stitched**  ✓ "])
    style id3 color:#02b802,stroke:none
  ```
</Frame>

### The `link_domain` method

The Converge Pixel exposes the `link_domain` method to automatically add the `?__cvg_uid={CVG_ID_VALUE}&__cvg_sid={CVG_SID_VALUE}` suffix to every outbound link that leads to `myotherdomain.com`.
Include the following method together with the basic Converge pixel snippet on the `myfirstdomain.com` website to enable it on every page.

```js theme={null}
cvg({ method: "link_domain", domain: "myotherdomain.com" });
```

<Note>
  Always validate that both `__cvg_uid` and `__cvg_sid` are present after navigating to another domain. If those are missing, Converge has no way of stitching the events correctly. This will potentially lead to sessions being attributed as organic referrals from your other domain.
</Note>

<Warning>
  If the redirect to `myotherdomain.com` doesn't happen directly through a link click but through JavaScript code, the parameter won't be added automatically.

  Follow [Manually setting up cross-domain tracking](#manually-setting-up-cross-domain-tracking) to manually instrument the links.
</Warning>

### Manually setting up cross-domain tracking

If the `link_domain` cannot be used in your case, you will need to manually instrument the links by adding the `__cvg_uid` and `__cvg_sid` URL parameters and their corresponding cookie values for each outbound link in that case.

The procedure for this will vary depending on your specific requirements. But in general, it consists of fetching the necessary cookie values and appending them to the URL before redirecting.

For example, assuming you are navigating to another domain using a click event on a button, one possible approach is the following:

```js theme={null}
document.getElementById('some-button').addEventListener('click', () => {
    // use your preferred way of reading cookie values
    let uid = getCookie('__cvg_uid')
    let sid = getCookie('__cvg_sid')

    window.location.href = `https://myotherdomain.com?__cvg_uid=${uid}&__cvg_sid=${sid}`
})
```

<Note>
  Always validate that both `__cvg_uid` and `__cvg_sid` are present after navigating to another domain. If those are missing, Converge has no way of stitching the events correctly. This will potentially lead to sessions being attributed as organic referrals from your other domain.
</Note>

***

## Manually instrumenting events

If the pre-built website integrations do not cover the entire [Converge event spec](/sources/converge-spec); or if you want to add custom events from your website then you will need to manually instrument these using the Converge Pixel.
You can use the `track` method in the Converge Pixel for this purpose.

<Note> As a general rule, you should always **aim to pass as many `properties`, `profileProperties` and `aliases` as possible** </Note>

The track method has the following parameters:

* `eventName`: The name of the event
* `properties`: The event properties you want to pass, covering the Converge Spec and possibly your own custom properties.
* `profileProperties`: The [profile properties](/sources/source-concepts#profile-properties)
* `aliases`: Any [aliases](/sources/source-concepts#aliases)

<AccordionGroup>
  <Info> You can find Converge JS examples for the entire [Converge Spec here](/sources/converge-spec) </Info>

  <Accordion title="Code Examples" icon="code">
    <CodeGroup>
      ```javascript Added To Cart theme={null}
      cvg({
        method: "track",
        eventName: "Added To Cart",
        properties: {
          product_id: "123456",
          variant_id: "78910",
          sku: "MY_SKU",
          name: "My Product",
          variant_name: "Vanilla",
          price: 42,
          currency: "USD",
          quantity: 1,
          vendor: "My Store",
        },
      });
      ```

      ```javascript Added Payment Info theme={null}
      cvg({
        method: "track",
        eventName: "Added Payment Info",
        properties: {
          total_price: 42,
          total_tax: 3.5,
          total_shipping: 2.4,
          currency: "USD",
          items: [
            {
              product_id: "123456",
              sku: "MY_SKU",
              name: "My Product",
              price: 42,
              currency: "USD",
              quantity: 1,
              vendor: "My Store",
            },
          ],
        },
        profileProperties: {
          // Pass if available
          $email: "john.smith@apple.com",
          $phone_number: "+199999999",
          $city: "San Francisco",
          $country_code: "US",
          $state: "California",
          $zip_code: "94103",
        },
        aliases: ["urn:email:john.smith@apple.com"],
      });

      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

## Turning off tracking for internal users

By appending the `internalUser=1` query parameter to the URL of the page you're visiting, you can prevent the Converge pixel from executing.
As a consequence, no events or sessions will be tracked. For example:

* `https://mywebsite.com?internalUser=1`
* `https://mywebsite.com/product-1?internalUser=1`
* `https://mywebsite.com/product-1?utm_source=test&internalUser=1`

<Note>
  This flag is stored under the `__cvg_internal_user` cookie and will persist for this browser, for as long as the cookie is present (up to 2 years).

  When conducting internal testing, it is advised to regularly add the `internalUser=1` query parameter to the URL to prevent tracking.
</Note>

***

## Event spec

This integration auto-tracks the following events with all properties available according to the [Converge event spec](/sources/converge-spec).

| Event Name                                       | Event Description             |
| ------------------------------------------------ | ----------------------------- |
| [\$page\_load](/sources/converge-spec#page-load) | When a customer views a page. |
