Skip to main content

SDK Initialization

The Fanfare SDK must be initialized before use. The init() function returns a configured SDK instance.

Basic Initialization

import Fanfare from "@waitify-io/fanfare-sdk-core";

const fanfare = await Fanfare.init({
  organizationId: "org_xxx",
  publishableKey: "pk_live_xxx",
});

Configuration Options

FanfareConfig

interface FanfareConfig {
  /**
   * Your Fanfare organization ID
   * Required - obtained from the Fanfare dashboard
   */
  organizationId: string;

  /**
   * Your publishable API key
   * Required - safe to expose in client-side code
   */
  publishableKey: string;

  /**
   * API environment
   * @default "production"
   */
  environment?: "production" | "staging" | "development";

  /**
   * Custom API URL (overrides environment)
   * Useful for testing against local or custom endpoints
   */
  apiUrl?: string;

  /**
   * Enable debug mode for verbose logging
   * @default false
   */
  debug?: boolean;

  /**
   * Authentication configuration
   */
  auth?: {
    /**
     * Whether to persist sessions in localStorage
     * @default true
     */
    persistSession?: boolean;

    /**
     * Session duration in seconds
     * @default 3600 (1 hour)
     */
    sessionDuration?: number;
  };

  /**
   * Logging configuration
   */
  logging?: {
    /**
     * Log level
     * @default "error"
     */
    level?: "error" | "warn" | "info" | "debug" | "metrics";
  };

  /**
   * Inter-tab synchronization configuration
   */
  sync?:
    | boolean
    | {
        /**
         * Whether sync is enabled
         * @default true
         */
        enabled?: boolean;

        /**
         * Which state keys to synchronize across tabs
         * @default ["session", "activeQueues", "activeDraws", "activeAuctions", "activeJourneys", "refreshToken"]
         */
        syncKeys?: string[];

        /**
         * Custom channel name for BroadcastChannel
         * @default "fanfare-sdk-sync"
         */
        channelName?: string;
      };

  /**
   * Feature flags for optional functionality
   */
  features?: {
    /**
     * Enable browser fingerprinting for device identification
     * Can be disabled for privacy compliance
     * @default true
     */
    fingerprinting?: boolean;
  };

  /**
   * Beacon event tracking configuration
   */
  beacon?: BeaconConfig;
}

BeaconConfig

interface BeaconConfig {
  /**
   * Whether beacon tracking is enabled
   * @default true
   */
  enabled?: boolean;

  /**
   * Maximum events to batch before sending
   * @default 10
   */
  batchSize?: number;

  /**
   * Flush interval in milliseconds
   * @default 5000
   */
  flushInterval?: number;

  /**
   * Maximum retries for failed sends
   * @default 3
   */
  maxRetries?: number;
}

Configuration Examples

Development Setup

const fanfare = await Fanfare.init({
  organizationId: "org_xxx",
  publishableKey: "pk_test_xxx", // Use test key
  environment: "development",
  debug: true,
  logging: {
    level: "debug",
  },
});

Production Setup

const fanfare = await Fanfare.init({
  organizationId: "org_xxx",
  publishableKey: "pk_live_xxx",
  environment: "production",
  debug: false,
  auth: {
    persistSession: true,
    sessionDuration: 7200, // 2 hours
  },
  beacon: {
    enabled: true,
    batchSize: 20,
  },
});

Disable Tab Sync

const fanfare = await Fanfare.init({
  organizationId: "org_xxx",
  publishableKey: "pk_live_xxx",
  sync: false, // Disable completely
});

// Or configure specific options
const fanfare = await Fanfare.init({
  organizationId: "org_xxx",
  publishableKey: "pk_live_xxx",
  sync: {
    enabled: true,
    syncKeys: ["session"], // Only sync session, not queue state
  },
});

Privacy-Focused Configuration

const fanfare = await Fanfare.init({
  organizationId: "org_xxx",
  publishableKey: "pk_live_xxx",
  features: {
    fingerprinting: false, // Disable device fingerprinting
  },
  beacon: {
    enabled: false, // Disable analytics
  },
  auth: {
    persistSession: false, // Don't persist to localStorage
  },
});

Session Restoration

After initialization, restore any existing session:
const fanfare = await Fanfare.init({
  organizationId: "org_xxx",
  publishableKey: "pk_live_xxx",
});

// Restore session and active experiences
const { session, experiences } = await fanfare.restore();

if (session) {
  console.log("Restored session:", session.consumerId);
  console.log("Active queues:", Object.keys(experiences.queues));
  console.log("Active draws:", Object.keys(experiences.draws));
}

// Resume polling for active experiences
await fanfare.resume();

RestoreResult

interface RestoreResult {
  session: Session | null;
  experiences: {
    queues: Record<string, QueueParticipation>;
    draws: Record<string, DrawParticipation>;
    auctions: Record<string, AuctionParticipation>;
    appointments: Record<string, unknown>;
    waitlists: Record<string, WaitlistParticipation>;
    timedReleases: Record<string, TimedReleaseParticipation>;
    experiences: Record<string, ExperienceSession>;
  };
}

Cleanup

Always destroy the SDK instance when done:
// In a React component
useEffect(() => {
  let fanfare: FanfareSDK;

  async function init() {
    fanfare = await Fanfare.init({
      organizationId: "org_xxx",
      publishableKey: "pk_live_xxx",
    });
  }

  init();

  return () => {
    fanfare?.destroy();
  };
}, []);
The destroy() method:
  • Stops all polling operations
  • Flushes pending beacon events
  • Closes tab sync channels
  • Cleans up event listeners
  • Note: Does not clear stored state (for page refresh handling)

Error Handling

Initialization can fail for various reasons:
import Fanfare, { FanfareError, ErrorCodes } from "@waitify-io/fanfare-sdk-core";

try {
  const fanfare = await Fanfare.init({
    organizationId: "org_xxx",
    publishableKey: "pk_live_xxx",
  });
} catch (error) {
  if (error instanceof FanfareError) {
    switch (error.code) {
      case ErrorCodes.INVALID_CONFIG:
        console.error("Invalid configuration:", error.message);
        break;
      case ErrorCodes.NETWORK_ERROR:
        console.error("Network error during init:", error.message);
        break;
      default:
        console.error("Initialization failed:", error.message);
    }
  }
}

Multiple Instances

While typically you’ll use a single SDK instance, you can create multiple instances for different organizations:
const fanfareOrg1 = await Fanfare.init({
  organizationId: "org_aaa",
  publishableKey: "pk_live_aaa",
  sync: {
    channelName: "fanfare-org-aaa", // Unique channel
  },
});

const fanfareOrg2 = await Fanfare.init({
  organizationId: "org_bbb",
  publishableKey: "pk_live_bbb",
  sync: {
    channelName: "fanfare-org-bbb", // Unique channel
  },
});

Environment Variables

For React applications, use environment variables:
// .env
VITE_FANFARE_ORG_ID = org_xxx;
VITE_FANFARE_KEY = pk_live_xxx;

// app.ts
const fanfare = await Fanfare.init({
  organizationId: import.meta.env.VITE_FANFARE_ORG_ID,
  publishableKey: import.meta.env.VITE_FANFARE_KEY,
});
For Next.js:
// .env.local
NEXT_PUBLIC_FANFARE_ORG_ID = org_xxx;
NEXT_PUBLIC_FANFARE_KEY = pk_live_xxx;

// app.ts
const fanfare = await Fanfare.init({
  organizationId: process.env.NEXT_PUBLIC_FANFARE_ORG_ID!,
  publishableKey: process.env.NEXT_PUBLIC_FANFARE_KEY!,
});

Next Steps