@reestify/affiliate
v0.1.3
Published
JavaScript SDK for affiliate tracking and attribution
Maintainers
Readme
@affiliate/sdk
JavaScript SDK for affiliate tracking and attribution. This SDK enables seamless integration of affiliate tracking into any website or web application.
Features
- 🔗 Automatic referral link detection from URL parameters
- 🍪 Cookie-based tracking with localStorage fallback
- 📊 Custom event tracking
- 🔄 Automatic retry with exponential backoff
- 🌐 Framework-agnostic (works with React, Vue, Next.js, vanilla JS)
- 📦 Tiny bundle size (~3KB gzipped)
- 🔒 TypeScript support with full type definitions
Installation
# Using npm
npm install @affiliate/sdk
# Using yarn
yarn add @affiliate/sdk
# Using bun
bun add @affiliate/sdk
# Using pnpm
pnpm add @affiliate/sdkQuick Start
import { AffiliateTracker } from '@affiliate/sdk'
// Create tracker instance
const tracker = new AffiliateTracker({
apiUrl: 'https://api.yoursite.com',
})
// Initialize tracking (call once on page load)
tracker.init()That's it! The SDK will automatically:
- Detect referral parameters in the URL (
?ref=abc123) - Store tracking data in a cookie
- Send a click event to your tracking server
Configuration Options
const tracker = new AffiliateTracker({
// Required
apiUrl: 'https://api.example.com', // Your API server URL
// Optional
cookieDomain: '.example.com', // Cookie domain (default: current domain)
cookieExpiration: 30, // Cookie expiration in days (default: 30)
debug: false, // Enable debug logging (default: false)
referralParams: ['ref', 'aff'], // URL params to detect (default: ['ref', 'aff', 'affiliate', 'via'])
// Retry configuration
retry: {
maxAttempts: 3, // Max retry attempts (default: 3)
initialDelay: 1000, // Initial delay in ms (default: 1000)
maxDelay: 30000, // Max delay in ms (default: 30000)
backoffMultiplier: 2, // Backoff multiplier (default: 2)
},
})API Reference
new AffiliateTracker(config)
Creates a new tracker instance.
Parameters:
config.apiUrl(required): Your API server URLconfig.cookieDomain(optional): Cookie domain for cross-subdomain trackingconfig.cookieExpiration(optional): Cookie expiration in days (default: 30)config.debug(optional): Enable debug logging (default: false)config.referralParams(optional): Array of URL parameter names to detectconfig.retry(optional): Retry configuration for failed requests
tracker.init()
Initializes the tracker. Call this once when your page loads.
- Detects referral parameters in the current URL
- Sets tracking cookie if referral is detected
- Sends click event to the tracking server
tracker.init()tracker.getReferralData()
Returns the current referral data if available.
Returns: ReferralData | null
const referral = tracker.getReferralData()
if (referral) {
console.log('Referred by:', referral.affiliateId)
console.log('Campaign:', referral.campaign)
}ReferralData structure:
interface ReferralData {
affiliateId: string // Affiliate identifier
linkCode?: string // Referral link code
campaign?: string // Campaign name
utmSource?: string // UTM source
utmMedium?: string // UTM medium
utmCampaign?: string // UTM campaign
timestamp: number // When referral was recorded
expiresAt: number // Expiration timestamp
}tracker.hasReferral()
Checks if there is an active (non-expired) referral.
Returns: boolean
if (tracker.hasReferral()) {
// Show affiliate-specific content
}tracker.trackEvent(eventType, metadata?)
Tracks a custom event.
Parameters:
eventType(required): Event type identifier (e.g., 'signup', 'purchase')metadata(optional): Additional event data
Returns: Promise<TrackEventResponse>
// Track a signup event
await tracker.trackEvent('signup', {
plan: 'pro',
value: 99,
})
// Track a purchase event
await tracker.trackEvent('purchase', {
orderId: 'order_123',
amount: 149.99,
currency: 'USD',
})tracker.clear()
Clears all tracking data (cookie and localStorage).
tracker.clear()tracker.isInitialized()
Checks if the tracker has been initialized.
Returns: boolean
URL Parameters
The SDK automatically detects these URL parameters:
| Parameter | Description |
|-----------|-------------|
| ref | Referral code |
| aff | Affiliate code |
| affiliate | Affiliate identifier |
| via | Referral source |
| affiliate_id | Affiliate ID |
| aid | Affiliate ID (short) |
| campaign | Campaign name |
| utm_source | UTM source |
| utm_medium | UTM medium |
| utm_campaign | UTM campaign |
Example URLs:
https://yoursite.com/?ref=abc123
https://yoursite.com/?aff=partner1&campaign=summer-sale
https://yoursite.com/?ref=xyz&utm_source=twitter&utm_medium=socialFramework Examples
Vanilla JavaScript
<script type="module">
import { AffiliateTracker } from '@affiliate/sdk'
const tracker = new AffiliateTracker({
apiUrl: 'https://api.example.com',
})
tracker.init()
// Track events on button clicks
document.getElementById('signup-btn').addEventListener('click', () => {
tracker.trackEvent('signup_click')
})
</script>React
import { useEffect } from 'react'
import { AffiliateTracker } from '@affiliate/sdk'
// Create tracker instance outside component
const tracker = new AffiliateTracker({
apiUrl: process.env.REACT_APP_API_URL!,
})
function App() {
useEffect(() => {
tracker.init()
}, [])
const handleSignup = async () => {
await tracker.trackEvent('signup', { plan: 'pro' })
// Continue with signup logic
}
return (
<button onClick={handleSignup}>
Sign Up
</button>
)
}React with Custom Hook
import { useEffect, useState, useCallback } from 'react'
import { AffiliateTracker, ReferralData } from '@affiliate/sdk'
const tracker = new AffiliateTracker({
apiUrl: process.env.REACT_APP_API_URL!,
})
export function useAffiliateTracker() {
const [referralData, setReferralData] = useState<ReferralData | null>(null)
const [isInitialized, setIsInitialized] = useState(false)
useEffect(() => {
tracker.init()
setReferralData(tracker.getReferralData())
setIsInitialized(true)
}, [])
const trackEvent = useCallback(
async (eventType: string, metadata?: Record<string, unknown>) => {
return tracker.trackEvent(eventType, metadata)
},
[]
)
return {
referralData,
isInitialized,
hasReferral: tracker.hasReferral(),
trackEvent,
}
}
// Usage in component
function SignupPage() {
const { referralData, trackEvent } = useAffiliateTracker()
const handleSignup = async () => {
await trackEvent('signup', { referredBy: referralData?.affiliateId })
}
return (
<div>
{referralData && <p>Referred by: {referralData.affiliateId}</p>}
<button onClick={handleSignup}>Sign Up</button>
</div>
)
}Next.js (App Router)
// app/providers.tsx
'use client'
import { useEffect } from 'react'
import { AffiliateTracker } from '@affiliate/sdk'
const tracker = new AffiliateTracker({
apiUrl: process.env.NEXT_PUBLIC_API_URL!,
})
export function AffiliateProvider({ children }: { children: React.ReactNode }) {
useEffect(() => {
tracker.init()
}, [])
return <>{children}</>
}
// app/layout.tsx
import { AffiliateProvider } from './providers'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html>
<body>
<AffiliateProvider>{children}</AffiliateProvider>
</body>
</html>
)
}Next.js (Pages Router)
// pages/_app.tsx
import { useEffect } from 'react'
import type { AppProps } from 'next/app'
import { AffiliateTracker } from '@affiliate/sdk'
const tracker = new AffiliateTracker({
apiUrl: process.env.NEXT_PUBLIC_API_URL!,
})
export default function App({ Component, pageProps }: AppProps) {
useEffect(() => {
tracker.init()
}, [])
return <Component {...pageProps} />
}Vue 3
<!-- App.vue -->
<script setup lang="ts">
import { onMounted } from 'vue'
import { AffiliateTracker } from '@affiliate/sdk'
const tracker = new AffiliateTracker({
apiUrl: import.meta.env.VITE_API_URL,
})
onMounted(() => {
tracker.init()
})
const handleSignup = async () => {
await tracker.trackEvent('signup')
}
</script>
<template>
<button @click="handleSignup">Sign Up</button>
</template>Vue 3 Composable
// composables/useAffiliateTracker.ts
import { ref, onMounted } from 'vue'
import { AffiliateTracker, ReferralData } from '@affiliate/sdk'
const tracker = new AffiliateTracker({
apiUrl: import.meta.env.VITE_API_URL,
})
export function useAffiliateTracker() {
const referralData = ref<ReferralData | null>(null)
const isInitialized = ref(false)
onMounted(() => {
tracker.init()
referralData.value = tracker.getReferralData()
isInitialized.value = true
})
const trackEvent = async (
eventType: string,
metadata?: Record<string, unknown>
) => {
return tracker.trackEvent(eventType, metadata)
}
return {
referralData,
isInitialized,
hasReferral: () => tracker.hasReferral(),
trackEvent,
}
}Troubleshooting
Cookies not being set
- Check domain configuration: If tracking across subdomains, set
cookieDomainto.yourdomain.com - HTTPS required: Secure cookies require HTTPS in production
- Third-party cookie blocking: The SDK falls back to localStorage if cookies are blocked
Referral not detected
- Check URL parameters: Ensure the URL contains one of the supported parameters
- Custom parameters: If using custom parameter names, configure
referralParams - Debug mode: Enable
debug: trueto see console logs
const tracker = new AffiliateTracker({
apiUrl: 'https://api.example.com',
debug: true, // Enable debug logging
})API requests failing
- Check CORS: Ensure your API server allows requests from your domain
- Network issues: The SDK automatically retries failed requests
- Check API URL: Verify the
apiUrlis correct and accessible
TypeScript errors
Ensure you have the correct TypeScript version (5.0+) and the types are properly resolved:
{
"compilerOptions": {
"moduleResolution": "bundler"
}
}Browser Support
- Chrome 80+
- Firefox 75+
- Safari 13+
- Edge 80+
The SDK uses modern JavaScript features but is compiled to ES2020 for broad compatibility.
Privacy Considerations
- IP addresses are hashed before storage
- Cookies are first-party only
- No personal data is collected without explicit tracking calls
- Respects browser cookie preferences
License
MIT
