Snippet Setup
This page is the HTML / plain-script installation guide for the Selgeo tracking snippet (selgeo.js) — a lightweight JavaScript file that runs on your website, registers partner referral clicks, and stores attribution data in the visitor's browser for later conversion matching. Use this guide if you control your site's raw HTML directly (static sites, Webflow, Shopify Liquid, custom server-rendered pages, or a tag manager).
- Next.js — see the Next.js guide for the
next/scriptcomponent pattern. - React (Vite) — see the React (Vite) guide for
index.htmlplacement and theuseEffectfallback. - WordPress — see the WordPress guide for Site Editor,
footer.php, and header-footer-plugin placement.
API Version: v1
Basic installation
Add the following <script> tag to every page of your website, just before the closing </body> tag:
<script
async
src="https://cdn.selgeo.com/v1/selgeo.js"
data-merchant="pk_test_YOUR_KEY"
></script>
Replace pk_test_YOUR_KEY with your public API key from the Selgeo dashboard (Settings > API Keys).
Required attributes
| Attribute | Description |
|---|---|
src | CDN URL for the snippet. Always use https://cdn.selgeo.com/v1/selgeo.js. |
data-merchant | Your public API key (pk_test_* for test mode, pk_live_* for live mode). |
async | Load the snippet asynchronously so it does not block page rendering. |
Optional attributes
| Attribute | Description |
|---|---|
data-debug | Enable debug logging in the browser console. Remove before going live. |
data-api-url | Override the API endpoint URL. For advanced use only (e.g., custom proxy). |
How it works
When a visitor arrives at your site with a ?ref= parameter in the URL (e.g., https://your-site.com/pricing?ref=abc123), the snippet:
- Detects the
refquery parameter. - Registers the click with the Selgeo API using your public key.
- Stores the
click_idreturned by the API in the browser'ssessionStorage. - Removes
?ref=from the URL usinghistory.replaceStateto keep URLs clean. - Rewrites Stripe Payment Links on the page to include
client_reference_id=CLICK_ID.
If there is no ?ref= parameter, the snippet does nothing. It has zero overhead on pages where no referral is taking place.
Storage mechanism
The snippet stores attribution data in sessionStorage, not cookies:
| Key | Value | Lifetime |
|---|---|---|
__selgeo_cid | The click_id (UUID) | Until the browser tab closes |
__selgeo_vtk | A visitor token (UUID) | Until the browser tab closes |
Privacy implications:
sessionStorageis tab-scoped -- it is not shared across tabs or windows.- Data is automatically cleared when the tab is closed.
- No cookies are set. No cookie consent banner is required for Selgeo tracking.
- The snippet sends no data to Selgeo unless a
?ref=parameter is present.
Reading the click ID
Your frontend code can read the stored click_id at any time:
const clickId = __selgeo.getClickId();
// Returns a UUID string (e.g., "f47ac10b-58cc-4372-a567-0e02b2c3d479")
// Returns null if no referral click was recorded in this session
This is useful when you need to pass the click_id to your backend -- for example, when creating a Stripe Checkout Session or calling the Conversion API.
Available methods
| Method | Returns | Description |
|---|---|---|
__selgeo.getClickId() | string | null | The current click ID, or null if none exists |
__selgeo.getVisitorToken() | string | null | The current visitor token, or null |
__selgeo.checkUrl() | void | Manually re-check the current URL for a ?ref= parameter |
Single-page applications (SPAs)
The snippet automatically monitors URL changes in single-page applications. It listens for:
popstateevents (browser back/forward navigation)history.pushStateandhistory.replaceStatecalls (programmatic navigation)
When the URL changes and contains a new ?ref= parameter, the snippet captures the click automatically. No additional configuration is needed for React, Vue, Angular, or other SPA frameworks.
If you dynamically construct URLs with ?ref= parameters and navigate programmatically, the snippet will detect the change automatically.
Manual URL check
In rare cases where the automatic detection does not trigger (e.g., the ?ref= parameter is added after page load via JavaScript without using history.pushState), you can manually tell the snippet to re-check:
__selgeo.checkUrl();
Stripe Payment Link auto-rewrite
If your page contains links to Stripe Payment Links (https://buy.stripe.com/...), the snippet automatically appends ?client_reference_id=CLICK_ID to them when a referral click is active.
<!-- Before snippet runs -->
<a href="https://buy.stripe.com/test_abc123">Subscribe</a>
<!-- After snippet runs (when a click_id is stored) -->
<a href="https://buy.stripe.com/test_abc123?client_reference_id=CLICK_ID">Subscribe</a>
The snippet also watches for dynamically added Payment Links (via MutationObserver) and rewrites them as they appear. This works with SPAs and lazily loaded content.
Merchant override protection: If you set client_reference_id on a Payment Link yourself, the snippet will not overwrite your value. Your explicit value always takes priority.
For a detailed walkthrough, see Stripe Payment Links.
Tag manager installation
If you use Google Tag Manager (GTM) or another tag manager, add the snippet as a custom HTML tag:
- Create a new Custom HTML tag in GTM.
- Paste the script tag:
<scriptasyncsrc="https://cdn.selgeo.com/v1/selgeo.js"data-merchant="pk_test_YOUR_KEY"></script>
- Set the trigger to All Pages.
- Publish the container.
When using a tag manager, the snippet may load slightly later than a direct <script> tag. This is fine for most use cases, but if you need the click_id available immediately on page load (e.g., to pass it to a server-rendered checkout form), add the snippet directly to your HTML instead.
Placement recommendations
| Scenario | Recommendation |
|---|---|
| Standard website | Add to every page via global layout/template |
| SPA (React, Vue, etc.) | Add to index.html once -- snippet handles route changes |
| Landing pages only | Add only to pages where partner traffic lands |
| Checkout page only | Not recommended -- the snippet must be on the landing page to capture the ?ref= parameter |
The ?ref= parameter is present only in the initial URL when the visitor clicks a partner link. If the snippet is not loaded on that page, the click will not be recorded and the click_id will not be available for later conversion attribution.
Verify your installation
- Add
data-debugto the script tag temporarily. - Visit your site with a test tracking link:
https://your-site.com/?ref=YOUR_TEST_REF - Open Developer Tools (F12) and check the Console for:
[selgeo] ref detected YOUR_TEST_REF[selgeo] click_id stored xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
- Check sessionStorage in the Application tab (Chrome) or Storage tab (Firefox):
__selgeo_cidshould contain a UUID__selgeo_vtkshould contain a UUID
- Call the API in the console:
__selgeo.getClickId() // Should return a UUID string
- Check the dashboard -- the click should appear in Analytics within seconds.
Troubleshooting
Snippet not loading
- Verify the
srcURL is exactlyhttps://cdn.selgeo.com/v1/selgeo.js. - Check for Content Security Policy (CSP) headers that may block the script. Add
cdn.selgeo.comto yourscript-srcdirective. - Check for ad blockers that may block the script.
click_id is null
- The visitor must arrive with a
?ref=parameter in the URL. Direct visits do not create aclick_id. - Check that
data-merchantcontains a valid public key (pk_test_*orpk_live_*). - Verify the
refvalue matches an active tracking link in your program.
Stripe Payment Links not rewritten
- The link
hrefmust start withhttps://buy.stripe.com. Relative URLs or proxied URLs are not detected. - The rewrite only happens when a
click_idis stored. Visit the page via a tracking link first. - If you set
client_reference_idyourself, the snippet will not overwrite it.
Performance
The snippet is designed to have minimal impact on your site:
| Metric | Value |
|---|---|
| Bundle size | < 5 KB gzipped |
| Initialization time | < 50 ms |
| Network requests | 0 (no referral) or 1 (referral click registration) |
| Cookies set | None |
| DOM modifications | None (except URL cleanup via history.replaceState) |
The snippet runs entirely in an IIFE (Immediately Invoked Function Expression) and does not pollute the global scope beyond the __selgeo API object.
Next steps
- Stripe Payment Links -- zero-backend Stripe integration
- Stripe Checkout -- pass
click_idto Checkout Sessions - Stripe Metadata -- pass
click_idthrough Checkout Session metadata (alternative toclient_reference_id) - Conversion API -- track non-Stripe conversions