npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

tiny-utm-keeper

v1.0.2

Published

Zero-dependency, TypeScript-first UTM parameter tracker for first-touch/last-touch attribution. SSR-friendly.

Downloads

13

Readme

🎯 tiny-utm-keeper

npm version npm downloads License: MIT TypeScript Bundle Size

ابزاری سبک، بدون وابستگی و TypeScript-first برای ردیابی و نگه‌داری پارامترهای UTM در جاوااسکریپت. مناسب برای Next.js و هر فریمورک دیگر با پشتیبانی کامل از SSR.


A zero-dependency, TypeScript-first UTM parameter tracker for first-touch/last-touch attribution. Built for JavaScript/TypeScript apps with full SSR support (Next.js friendly).

✨ Features

  • 🎯 Zero Dependencies - Lightweight and fast
  • 📦 TypeScript-First - Full type safety out of the box
  • 🔄 First-Touch & Last-Touch - Flexible attribution modes
  • 💾 Persistent Storage - Configurable expiration (7/30/90 days)
  • 🌐 SSR-Friendly - Works seamlessly with Next.js and other SSR frameworks
  • 🔗 Auto-Injection - Automatically append UTMs to links and fetch requests
  • 📊 Analytics Ready - Easy integration with analytics and attribution systems
  • 🛡️ Type-Safe - Full TypeScript support with comprehensive types

📦 Installation

npm install tiny-utm-keeper
yarn add tiny-utm-keeper
pnpm add tiny-utm-keeper

🚀 Quick Start

Basic Usage

import { init, getUTMs, appendToURL } from 'tiny-utm-keeper';

// Initialize and auto-capture UTMs from current URL
init({
  mode: 'first-touch',    // or 'last-touch'
  expirationDays: 30,     // Store for 30 days
  autoCapture: true       // Automatically capture on init
});

// Get stored UTM parameters
const utms = getUTMs();
console.log(utms);
// { utm_source: 'google', utm_medium: 'cpc', utm_campaign: 'summer_sale' }

// Append UTMs to any URL
const ctaLink = appendToURL('https://example.com/signup');
// https://example.com/signup?utm_source=google&utm_medium=cpc&utm_campaign=summer_sale

Next.js Usage

// app/providers.tsx or pages/_app.tsx
'use client'; // for Next.js 13+ app directory

import { useEffect } from 'react';
import { init } from 'tiny-utm-keeper';

export function UTMProvider({ children }: { children: React.ReactNode }) {
  useEffect(() => {
    // Initialize on client-side only
    init({
      mode: 'first-touch',
      expirationDays: 30,
    });
  }, []);

  return <>{children}</>;
}
// app/layout.tsx or pages/_app.tsx
import { UTMProvider } from './providers';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <UTMProvider>
          {children}
        </UTMProvider>
      </body>
    </html>
  );
}

📚 API Reference

Initialization

init(config?: UTMKeeperConfig): UTMKeeper

Initialize the default UTMKeeper instance.

import { init } from 'tiny-utm-keeper';

const keeper = init({
  mode: 'first-touch',        // Attribution mode
  expirationDays: 30,         // Storage duration
  storageKey: 'utm_keeper',   // localStorage key
  autoCapture: true,          // Auto-capture on init
  captureUrl: undefined       // Custom URL to capture from
});

Core Functions

capture(url?: string): boolean

Manually capture UTM parameters from URL.

import { capture } from 'tiny-utm-keeper';

// Capture from current URL
capture();

// Capture from specific URL
capture('https://example.com?utm_source=facebook&utm_medium=social');

getUTMs(): UTMParams | null

Get stored UTM parameters.

import { getUTMs } from 'tiny-utm-keeper';

const utms = getUTMs();
if (utms) {
  console.log(utms.utm_source);  // 'google'
  console.log(utms.utm_medium);  // 'cpc'
  console.log(utms.utm_campaign); // 'summer_sale'
}

appendToURL(url: string): string

Append stored UTMs to a URL.

import { appendToURL } from 'tiny-utm-keeper';

const link = appendToURL('https://example.com/pricing');
// https://example.com/pricing?utm_source=google&utm_medium=cpc...

getUTMObject(): Record<string, string>

Get UTMs as a plain object (useful for API calls).

import { getUTMObject } from 'tiny-utm-keeper';

const utmData = getUTMObject();

// Use in API calls
fetch('/api/signup', {
  method: 'POST',
  body: JSON.stringify({
    email: '[email protected]',
    ...utmData  // Inject UTMs
  })
});

clear(): boolean

Clear stored UTM parameters.

import { clear } from 'tiny-utm-keeper';

clear(); // Remove stored UTMs

Fetch Integration

createFetch(): typeof fetch

Create a fetch wrapper that automatically injects UTMs.

import { createFetch } from 'tiny-utm-keeper';

const utmFetch = createFetch();

// UTMs automatically added to query string
utmFetch('https://api.example.com/data')
  .then(res => res.json())
  .then(data => console.log(data));

// Skip UTM injection for specific request
utmFetch('https://api.example.com/public', { 
  skipUTM: true 
});

Class API

import { UTMKeeper } from 'tiny-utm-keeper';

// Create custom instance
const keeper = new UTMKeeper({
  mode: 'last-touch',
  expirationDays: 7
});

keeper.capture();
keeper.getUTMs();
keeper.appendToURL('https://example.com');
keeper.clear();
keeper.hasStoredUTMs();
keeper.getMode();
keeper.setMode('first-touch');

🎨 Use Cases

1. First-Touch Attribution for Signup

نگه‌داری منبع اصلی کاربر برای ۳۰ روز و استفاده در فرم ثبت‌نام

import { init, getUTMObject } from 'tiny-utm-keeper';

// Initialize with first-touch mode
init({ mode: 'first-touch', expirationDays: 30 });

// In your signup form
async function handleSignup(email: string, password: string) {
  const utms = getUTMObject();
  
  const response = await fetch('/api/signup', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      email,
      password,
      ...utms  // Include original attribution data
    })
  });
  
  return response.json();
}

2. Auto-Append UTMs to CTA Links

افزودن خودکار UTMهای ذخیره‌شده به لینک‌های کمپین

import { appendToURL } from 'tiny-utm-keeper';

function CTAButton() {
  const href = appendToURL('https://example.com/pricing');
  
  return <a href={href}>Start Free Trial</a>;
}

3. Fetch Interceptor for Backend Attribution

تزریق خودکار UTMها به درخواست‌های API

import { createFetch } from 'tiny-utm-keeper';

// Create UTM-enabled fetch
const utmFetch = createFetch();

// Replace global fetch (optional)
if (typeof window !== 'undefined') {
  window.fetch = utmFetch;
}

// All fetch calls now include UTMs automatically
fetch('/api/analytics')
  .then(res => res.json())
  .then(data => console.log(data));

4. Analytics Integration

import { getUTMs, hasStoredUTMs } from 'tiny-utm-keeper';

function trackPageView() {
  if (hasStoredUTMs()) {
    const utms = getUTMs();
    
    // Send to analytics
    analytics.track('Page View', {
      ...utms,
      page: window.location.pathname
    });
  }
}

5. A/B Testing with Attribution

import { getUTMs } from 'tiny-utm-keeper';

function getExperimentVariant() {
  const utms = getUTMs();
  
  // Show different variant based on traffic source
  if (utms?.utm_source === 'google') {
    return 'variant-a';
  }
  
  return 'variant-b';
}

🔧 Configuration Options

interface UTMKeeperConfig {
  /**
   * Attribution mode: 'first-touch' or 'last-touch'
   * @default 'first-touch'
   */
  mode?: 'first-touch' | 'last-touch';
  
  /**
   * Expiration time in days
   * @default 30
   */
  expirationDays?: number;
  
  /**
   * localStorage key prefix
   * @default 'utm_keeper'
   */
  storageKey?: string;
  
  /**
   * Automatically capture UTMs on init
   * @default true
   */
  autoCapture?: boolean;
  
  /**
   * Custom URL to capture UTMs from
   */
  captureUrl?: string;
}

🌐 SSR Support

The library is fully SSR-safe and will gracefully handle server-side environments:

  • All storage operations check for browser environment
  • Safe to import and initialize in Next.js app/page components
  • No errors or warnings in server-side rendering
  • Automatically activates only on client-side

📊 Supported UTM Parameters

  • utm_source - Traffic source (e.g., google, facebook)
  • utm_medium - Marketing medium (e.g., cpc, email, social)
  • utm_campaign - Campaign name (e.g., summer_sale)
  • utm_term - Paid search keywords
  • utm_content - A/B testing content variation

🤝 TypeScript Support

Full TypeScript support with comprehensive type definitions:

import type { 
  UTMParams, 
  UTMKeeperConfig, 
  AttributionMode,
  StoredUTMData 
} from 'tiny-utm-keeper';

📝 License

MIT

🙏 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.


ساخته شده با ❤️ برای جامعه توسعه‌دهندگان

Made with ❤️ for the developer community