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

# React Integration

> Install AgentRef in a React app without duplicate script injection or broken attribution in SPA navigation.

For plain React apps, the main goal is simple: load the AgentRef script once at the app shell and keep it available while the SPA navigates.

## Before you start

* Set the program website in AgentRef to the same root domain your React app uses.
* Copy the exact AgentRef script snippet from `Settings -> Integration`.
* If checkout happens on a sibling subdomain, install AgentRef there too.

## Recommended installation

<Tabs>
  <Tab title="index.html">
    For Vite, CRA, and most React SPAs, the cleanest setup is to add the script directly to the shared HTML shell.

    ```html theme={null}
    <!-- public/index.html or index.html -->
    <script
      defer
      src="https://www.agentref.co/api/tracking/script.js?pid=YOUR_PROGRAM_ID"
    ></script>
    ```
  </Tab>

  <Tab title="Root component fallback">
    If you do not control the HTML shell, inject the script once from the root component and guard against duplicates.

    ```tsx theme={null}
    import { useEffect } from 'react';

    export function AgentRefTracking() {
      useEffect(() => {
        if (document.querySelector('script[src*="/api/tracking/script.js"]')) {
          return;
        }

        const script = document.createElement('script');
        script.defer = true;
        script.src = 'https://www.agentref.co/api/tracking/script.js?pid=YOUR_PROGRAM_ID';
        document.head.appendChild(script);
      }, []);

      return null;
    }
    ```
  </Tab>
</Tabs>

<Tip>
  If you run React Strict Mode in development, an `index.html` install is usually less noisy than effect-based injection because it avoids duplicate development mounts.
</Tip>

## Checkout compatibility in React

| Checkout pattern                                                         | Recommendation                                                                                                                            |
| ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| Stripe Payment Links, Buy Buttons, or Pricing Tables rendered by the SPA | Supported directly. AgentRef already observes late-rendered Stripe elements.                                                              |
| React app calls your own backend to create a Stripe Checkout Session     | Supported, but you must forward `window.AgentRef.getCheckoutMetadata()` to your server. Use the [Stripe guide](/docs/integration/stripe). |
| Checkout jumps to a different root domain                                | First-party cookies do not cross root domains automatically.                                                                              |

## SPA-specific notes

* AgentRef does not need to be reloaded on every route change.
* Hosted Stripe surfaces that render after navigation are still covered because the script watches the DOM.
* If you gate cookies behind consent, call `window.AgentRef.setConsent('granted')` after the visitor accepts.

## Verify the installation

1. Land on the app through a real affiliate link.
2. Confirm `agentref_cid` and `agentref_pid` in DevTools.
3. Add `?agentref_debug=1` and inspect the console.
4. Complete one supported checkout flow and confirm AgentRef records the conversion.

## Troubleshooting

* The script appears multiple times in the DOM: move the install into `index.html` or add a duplicate guard.
* Referral cookies are missing after a route transition: the problem is usually that the script never loaded on first render.
* Payment Links work but custom checkout does not: that means your React frontend is fine and your Stripe backend still needs the metadata bridge.

## Related docs

<CardGroup cols={3}>
  <Card title="Stripe Checkout" icon="credit-card" href="/docs/integration/stripe">
    Bridge browser attribution into Stripe metadata.
  </Card>

  <Card title="Debug Mode" icon="bug" href="/docs/tracking/debug-mode">
    Inspect runtime state and hosted Stripe instrumentation.
  </Card>

  <Card title="Consent and GDPR" icon="shield" href="/docs/tracking/consent-gdpr">
    Coordinate AgentRef with your consent banner.
  </Card>
</CardGroup>
