RefRef Attribution Script
A lightweight, flexible attribution script for tracking referral codes in web applications. The attribution script captures referral codes from URL parameters, stores them in cookies, and automatically injects them into forms for seamless referral tracking.
Features
- Automatic referral code tracking - Captures
refcodefrom URL parameters (?refcode=ABC123) - Persistent cookie storage - Stores referral codes in cookies for 90-day tracking
- Smart form attachment - Only attaches to forms when a referral code exists (no empty fields)
- Dynamic form detection - MutationObserver automatically detects forms added after page load (SPAs, modals)
- Flexible auto-attach modes - Choose between "data-refref" (default), "all", or "false"
- Simple script tag configuration - All configuration via HTML attributes (no JavaScript required)
- MDN-compliant cookie options - Supports all standard Set-Cookie attributes
- Auto-detect HTTPS - Automatically adds Secure attribute on HTTPS sites
- TypeScript support - Fully typed with exported types
- Framework agnostic - Works with React, Vue, Svelte, plain HTML, and all modern frameworks
- Zero configuration - Works out of the box with sensible defaults
Installation
Add the script tag to your HTML (typically in the or before closing ):
The script automatically initializes when the DOM is ready. No additional configuration required.
Quick Start
Default Behavior (Opt-In Mode)
By default, the script only attaches to forms with the data-refref attribute:
<form data-refref action="/signup" method="POST">
<input type="email" name="email" required />
<button type="submit">Sign Upbutton>
form>
<form action="/search" method="GET">
<input type="text" name="query" />
<button type="submit">Searchbutton>
form>
When a user visits https://yoursite.com?refcode=ABC123:
- The code is saved to a cookie for 90 days
- Forms with
data-refrefget a hidden - Dynamically added forms with
data-refrefare automatically detected
Auto-Attach Modes
Control which forms get referral tracking using the data-auto-attach attribute:
Mode: "data-refref" (Default, Recommended)
Only attaches to forms with the data-refref attribute. This is the default and recommended mode.
<script
src="https://assets.refref.ai/attribution.v1.js"
data-auto-attach="data-refref"
>script>
<form data-refref action="/signup" method="POST">
<input type="email" name="email" />
<button>Sign Upbutton>
form>
<form action="/search" method="GET">
<input type="text" name="query" />
<button>Searchbutton>
form>
Use when:
- You want explicit control over which forms include referral codes
- You have non-referral forms (search, filters, internal forms) to exclude
- You prefer opt-in behavior (recommended for most use cases)
- You want to avoid cluttering every form with hidden fields
Mode: "all"
Attaches to ALL forms on the page, regardless of data-refref attribute.
src="https://assets.refref.ai/attribution.v1.js"
data-auto-attach="all"
>script>
<form action="/signup" method="POST">
<input type="email" name="email" />
<button>Sign Upbutton>
form>
<form action="/contact" method="POST">
<input type="text" name="name" />
<button>Contactbutton>
form>
Use when:
- You want to track every single form on your site
- Your site only has referral-related forms
- You want the simplest setup (no attributes to add)
Note: This attaches to ALL forms including search forms, filter forms, etc. Be intentional about this choice.
Mode: "false"
No automatic attachment. Use manual API calls only.
src="https://assets.refref.ai/attribution.v1.js"
data-auto-attach="false"
>script>
<script>
// Manually attach to specific forms
const signupForm = document.querySelector("#signup-form");
window.RefRefAttribution.attachTo(signupForm);
// Or attach to all forms manually
window.RefRefAttribution.attachToAll(); // Respects auto-attach mode
script>
Use when:
- You need full manual control over form attachment
- You have custom logic for when/how to attach
- Performance-sensitive scenarios (no MutationObserver overhead)
- Advanced integrations with custom frameworks
Note: MutationObserver is disabled in this mode. You must manually call attachTo() for dynamically added forms.
Cookie Configuration
Configure cookie behavior using the data-cookie-options attribute with a JSON string:
src="https://assets.refref.ai/attribution.v1.js"
data-cookie-options='{"Domain":".example.com","Max-Age":7776000,"SameSite":"Strict"}'
>script>
Default Cookie Options
The script uses these defaults (no configuration needed):
- Path:
/(available across your entire site) - Max-Age:
7776000(90 days in seconds) - SameSite:
Lax(allows cross-site referrals) - Secure: Auto-detected (added automatically on HTTPS, omitted on HTTP)
Available Cookie Attributes
The script accepts any MDN-compliant Set-Cookie attribute. Common options:
| Attribute | Type | Example | Description |
|---|---|---|---|
Domain |
string | ".example.com" |
Cookie domain (include subdomains with leading .) |
Path |
string | "/" |
Cookie path |
Max-Age |
number | 7776000 |
Cookie lifetime in seconds (90 days default) |
SameSite |
string | "Strict" | "Lax" | "None" |
Cookie same-site policy |
Secure |
boolean | true |
Only send over HTTPS (auto-detected by default) |
HttpOnly |
boolean | true |
Prevent JavaScript access (not recommended for this use case) |
Partitioned |
boolean | true |
CHIPS (Chrome privacy feature) |
Priority |
string | "High" |
Cookie priority |
Full list of attributes: See MDN Set-Cookie documentation
Example Configurations
Subdomain tracking (e.g., app.example.com and www.example.com):
src="https://assets.refref.ai/attribution.v1.js"
data-cookie-options='{"Domain":".example.com"}'
>script>
Strict same-site policy:
src="https://assets.refref.ai/attribution.v1.js"
data-cookie-options='{"SameSite":"Strict"}'
>script>
Custom expiration (30 days):
src="https://assets.refref.ai/attribution.v1.js"
data-cookie-options='{"Max-Age":2592000}'
>script>
Multiple options:
src="https://assets.refref.ai/attribution.v1.js"
data-cookie-options='{"Domain":".example.com","Max-Age":2592000,"SameSite":"Strict","Secure":true}'
>script>
Auto-Detect Secure Attribute
The Secure attribute is automatically added based on the page protocol:
- HTTPS:
Secureattribute is automatically added to cookies - HTTP:
Secureattribute is NOT added (allows cookies to work on localhost)
You can override this by explicitly setting Secure in data-cookie-options.
Invalid JSON Handling
If the data-cookie-options JSON is invalid, the script:
- Logs a warning to the console
- Falls back to default cookie options
- Continues to function normally
How It Works
- Auto-initialization: Script initializes automatically when DOM is ready
- URL parameter check: Looks for
?refcode=ABC123in the URL - Cookie check: If no URL parameter, checks for existing cookie (
refref-refcode) - Priority: URL parameters override cookie values (refreshes the cookie)
- Cookie storage: Saves referral code to cookie if found (90-day default)
- Form attachment (only when referral code exists):
- Mode "data-refref" (default): Injects hidden fields into forms with
data-refrefattribute - Mode "all": Injects hidden fields into ALL forms
- Mode "false": No automatic injection
- Mode "data-refref" (default): Injects hidden fields into forms with
- Dynamic detection: MutationObserver watches for new forms and auto-attaches (for "all" and "data-refref" modes)
Important: Forms Only Attach When Code Exists
The script only injects hidden fields when a referral code exists (from URL or cookie). This prevents empty fields from cluttering your forms.
Example:
<form data-refref>
<input type="email" name="email" />
form>
<form data-refref>
<input type="email" name="email" />
<input type="hidden" name="refcode" value="ABC123" />
form>
Form Integration
Injected Hidden Fields
When a referral code exists, the script injects:
- Field name: Always
"refcode"(not configurable) - Field value: The referral code from URL or cookie
- Injection behavior: Creates new field or updates existing field with same name
- Conditional: Only injected when referral code exists
Dynamic Forms (SPAs, Modals, Lazy-Loaded Content)
The MutationObserver automatically detects forms added after page load:
setTimeout(() => {
const modalForm = document.createElement("form");
modalForm.setAttribute("data-refref", "");
modalForm.innerHTML = `
`;
document.body.appendChild(modalForm);
// MutationObserver automatically detects and attaches
}, 2000);
Note: MutationObserver is active for "all" and "data-refref" modes. It's disabled in "false" mode.
Public API
The script exposes window.RefRefAttribution with the following methods:
getCode(): string | undefined
Get the current referral code (from URL or cookie).
console.log(code); // "ABC123" or undefined
Returns:
string: The referral code if presentundefined: No referral code found
attachTo(form: HTMLFormElement): void
Manually attach referral tracking to a specific form.
window.RefRefAttribution.attachTo(form);
Parameters:
form: The form element to attach to
Behavior:
- Creates/updates hidden
field - Only sets value if referral code exists
attachToAll(): void
Manually attach referral tracking to all forms (respects data-auto-attach mode).
Behavior (based on current mode):
- "data-refref": Attaches to forms with
data-refrefattribute - "all": Attaches to ALL forms
- "false": No-op (does nothing)
Use case: Call after dynamically adding multiple forms in "false" mode.
stopObserver(): void
Stop the MutationObserver from watching for new forms.
Use cases:
- Performance optimization (if you know no more forms will be added)
- Cleanup before page unload
- Switching to fully manual control
Note: After calling stopObserver(), dynamically added forms won't be automatically tracked. You must manually call attachTo() or attachToAll().
Complete Examples
Example 1: Default Setup (Opt-In with data-refref)
<html>
<head>
<script src="https://assets.refref.ai/attribution.v1.js">script>
head>
<body>
<form data-refref action="/signup" method="POST">
<input type="email" name="email" required />
<input type="password" name="password" required />
<button type="submit">Sign Upbutton>
form>
<form action="/search" method="GET">
<input type="text" name="query" />
<button type="submit">Searchbutton>
form>
body>
html>
Example 2: Track All Forms
<html>
<head>
<script
src="https://assets.refref.ai/attribution.v1.js"
data-auto-attach="all"
>script>
head>
<body>
<form action="/signup" method="POST">
<input type="email" name="email" />
<button type="submit">Sign Upbutton>
form>
<form action="/contact" method="POST">
<input type="text" name="name" />
<button type="submit">Contactbutton>
form>
body>
html>