Streakfox
Sdk

Web SDK

Install the JavaScript SDK to embed streak mechanics in any web property.

The Web SDK (@streakdev/web) provides a type-safe way to integrate Streakfox into JavaScript and TypeScript applications.

Installation

npm install @streakdev/web
# or
pnpm add @streakdev/web
# or
yarn add @streakdev/web

Quick Start

import { createClient, ensureUserHash, getVisitorId } from '@streakdev/web';

// Create a client (do this once)
const client = createClient({
  baseUrl: 'https://api.streakfox.com',
});

// Get a stable user identifier
const userHash = ensureUserHash(undefined, currentUser?.id ?? getVisitorId());

// Record an event
await client.recordEvent({
  projectId: 'YOUR_PROJECT_ID',
  event: 'like',
  userHash,
});

API Reference

createClient(options)

Creates a Streakfox API client.

const client = createClient({
  baseUrl: 'https://api.streakfox.com', // API endpoint
  adminToken: 'sk_...', // Optional: for server-side aliasUser calls
});

Options:

  • baseUrl — API endpoint (defaults to production)
  • adminToken — Required for aliasUser() (server-side only)
  • headers — Custom headers to include in requests

client.recordEvent(input)

Records a streak event for a user.

await client.recordEvent({
  projectId: 'proj_abc123',       // Required: your project ID
  event: 'like',                   // Required: action type
  userHash: 'user_hash_here',      // Required: user identifier
  meta: { postId: '123' },         // Optional: custom metadata
  idempotencyKey: 'unique-id',     // Optional: prevent duplicates
});

Input fields:

FieldTypeRequiredDescription
projectIdstringYour project ID from the dashboard
eventstringThe action type (e.g., 'like', 'visit', 'purchase')
kindstringLegacy alias for event
userHashstringUnique user identifier (use ensureUserHash)
metaobjectCustom metadata attached to the event
idempotencyKeystringPrevents duplicate processing
sessionIdstringGroup events by session

client.getState(input)

Fetches the current widget state for a user.

const state = await client.getState({
  projectId: 'proj_abc123',
  userHash: 'user_hash_here',
  event: 'like',
});

console.log(state.streak.current); // Current streak count
console.log(state.streak.best);    // Best streak ever
console.log(state.week);           // Last 7 days activity

client.aliasUser(input) (Server-side only)

Links an anonymous visitor to an authenticated user. This merges their streak history.

// Requires adminToken in client options
await client.aliasUser({
  projectId: 'proj_abc123',
  anonymousId: 'anon_visitor_id',
  userHash: 'authenticated_user_hash',
});

⚠️ This requires an adminToken and should only be called from your server, not client-side code.


Helper Functions

ensureUserHash(knownHash?, fallbackId?)

Generates or retrieves a consistent user hash for identifying users.

import { ensureUserHash, getVisitorId } from '@streakdev/web';

// For anonymous users
const hash = ensureUserHash(undefined, getVisitorId());

// For authenticated users
const hash = ensureUserHash(undefined, user.id);

// If you already have a hash
const hash = ensureUserHash(existingHash);

getVisitorId()

Returns a persistent anonymous visitor ID stored in localStorage.

import { getVisitorId } from '@streakdev/web';

const visitorId = getVisitorId(); // e.g., "v_abc123..."

React Integration

Custom Hook Example

import { createClient, ensureUserHash, getVisitorId } from '@streakdev/web';
import { useCallback, useMemo } from 'react';

const PROJECT_ID = process.env.NEXT_PUBLIC_STREAK_PROJECT_ID!;

export function useStreak(userId?: string) {
  const client = useMemo(
    () => createClient({ baseUrl: 'https://api.streakfox.com' }),
    []
  );

  const userHash = useMemo(
    () => ensureUserHash(undefined, userId ?? getVisitorId()),
    [userId]
  );

  const recordEvent = useCallback(
    (event: string, meta?: Record<string, unknown>) =>
      client.recordEvent({ projectId: PROJECT_ID, event, userHash, meta }),
    [client, userHash]
  );

  const getState = useCallback(
    (event: string) =>
      client.getState({ projectId: PROJECT_ID, event, userHash }),
    [client, userHash]
  );

  return { recordEvent, getState, userHash };
}

Usage

function LikeButton({ postId }: { postId: string }) {
  const { recordEvent } = useStreak(user?.id);

  const handleLike = async () => {
    await likePost(postId);
    await recordEvent('like', { postId });
  };

  return <button onClick={handleLike}>Like</button>;
}

Server-Side Usage (Node.js)

import { createClient } from '@streakdev/web';

const client = createClient({
  baseUrl: 'https://api.streakfox.com',
  adminToken: process.env.STREAK_ADMIN_TOKEN, // For aliasUser
});

// Record server-side events
export async function recordPurchase(userId: string, orderId: string) {
  await client.recordEvent({
    projectId: process.env.STREAK_PROJECT_ID!,
    event: 'purchase',
    userHash: hashUserId(userId),
    meta: { orderId },
  });
}

// Merge anonymous to authenticated user
export async function onUserLogin(anonymousId: string, userId: string) {
  await client.aliasUser({
    projectId: process.env.STREAK_PROJECT_ID!,
    anonymousId,
    userHash: hashUserId(userId),
  });
}

Next Steps

On this page