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/webQuick 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 foraliasUser()(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:
| Field | Type | Required | Description |
|---|---|---|---|
projectId | string | ✅ | Your project ID from the dashboard |
event | string | ✅ | The action type (e.g., 'like', 'visit', 'purchase') |
kind | string | ❌ | Legacy alias for event |
userHash | string | ✅ | Unique user identifier (use ensureUserHash) |
meta | object | ❌ | Custom metadata attached to the event |
idempotencyKey | string | ❌ | Prevents duplicate processing |
sessionId | string | ❌ | Group 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 activityclient.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
adminTokenand 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
- Action-Based Streaks — Trigger streaks from code
- Connecting Users — Merge anonymous and authenticated users
- Events API — Direct REST API access