Documentation Index
Fetch the complete documentation index at: https://docs.fanfare.io/llms.txt
Use this file to discover all available pages before exploring further.
Hooks Overview
The React SDK provides hooks for all experience types. Each hook follows a consistent pattern with state management, actions, and automatic event subscriptions.
Available Hooks
| Hook | Description | See Also |
|---|
useFanfare() | Access SDK instance | Context |
useFanfareAuth() | Authentication state and methods | Auth Hook |
useQueue(queueId) | Queue operations and state | useQueue |
useDraw(drawId) | Draw operations and state | useDraw |
useAuction(auctionId) | Auction operations and state | useAuction |
useWaitlist(waitlistId) | Waitlist operations and state | useWaitlist |
useTimedRelease(id) | Timed release operations | useTimedRelease |
useExperienceJourney(id) | Journey orchestration | useExperienceJourney |
Common Hook Pattern
All experience hooks share a consistent interface:
interface UseExperienceHook {
// Loading state
isLoading: boolean;
// Error state
error: Error | null;
// Client-friendly status
status: ClientStatus;
// Experience-specific state...
// Actions
enter: (metadata?: Record<string, unknown>) => Promise<void>;
leave: () => Promise<void>;
refreshStatus: () => Promise<void>;
// Experience-specific actions...
}
useFanfareAuth
Hook for authentication state and methods.
function useFanfareAuth(): {
isAuthenticated: boolean;
isGuest: boolean | undefined;
session: Session | undefined;
guest: () => Promise<GuestSession>;
requestOtp: (options: OtpRequest) => Promise<void>;
verifyOtp: (options: OtpVerify) => Promise<AuthenticatedSession>;
logout: () => Promise<void>;
};
Usage
import { useFanfareAuth } from "@waitify-io/fanfare-sdk-react";
function AuthComponent() {
const { isAuthenticated, isGuest, session, guest, requestOtp, verifyOtp, logout } = useFanfareAuth();
if (!isAuthenticated && !isGuest) {
return (
<div>
<button onClick={guest}>Continue as Guest</button>
<button onClick={() => requestOtp({ email: "[email protected]" })}>Login with Email</button>
</div>
);
}
if (isGuest) {
return (
<div>
<p>Guest session: {session?.consumerId}</p>
<button onClick={() => requestOtp({ email: "[email protected]" })}>Upgrade to Account</button>
</div>
);
}
return (
<div>
<p>Logged in as: {session?.email}</p>
<button onClick={logout}>Logout</button>
</div>
);
}
OTP Flow
function OtpLogin() {
const { requestOtp, verifyOtp } = useFanfareAuth();
const [email, setEmail] = useState("");
const [code, setCode] = useState("");
const [step, setStep] = useState<"email" | "code">("email");
const handleRequestOtp = async () => {
await requestOtp({ email });
setStep("code");
};
const handleVerifyOtp = async () => {
await verifyOtp({ email, code });
};
if (step === "email") {
return (
<div>
<input value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Email" />
<button onClick={handleRequestOtp}>Send Code</button>
</div>
);
}
return (
<div>
<input value={code} onChange={(e) => setCode(e.target.value)} placeholder="Enter code" />
<button onClick={handleVerifyOtp}>Verify</button>
</div>
);
}
Quick Reference
useQueue
const {
queue, // Queue details
status, // QueueConsumerState
position, // number | null
isLoading,
error,
enter, // () => Promise<QueueEnterResult>
leave, // () => Promise<void>
} = useQueue("queue_123");
useDraw
const {
draw, // Draw details
status, // UseDrawClientStatus
consumerState, // DrawConsumerState
isEntered,
isWinner,
admissionToken,
result, // DrawResult | null
isLoading,
error,
enter, // (metadata?) => Promise<DrawConsumerState>
withdraw, // () => Promise<void>
refreshStatus, // () => Promise<DrawConsumerState | null>
checkResult, // () => Promise<DrawResult | null>
} = useDraw("draw_123");
useAuction
const {
details, // AuctionDetails
status, // UseAuctionClientStatus
currentBid, // string | null
myBid, // string | null
minNextBid, // string | null
bidIncrement, // string | null
reservePrice, // string | null
reserveMet, // boolean
bidCount, // number
bidHistory, // Bid[]
timeRemaining, // number | null
isWinning, // boolean
autoRebidConfig, // AutoRebidConfig | null
isLoading,
error,
enter, // () => Promise<void>
leave, // () => Promise<void>
placeBid, // (amount: string) => Promise<BidResult>
refreshStatus, // () => Promise<AuctionStatus | null>
refreshHistory, // () => Promise<Bid[]>
enableAutoRebid, // (maxBid, increment) => void
disableAutoRebid, // () => void
} = useAuction("auction_123");
useWaitlist
const {
status, // UseWaitlistClientStatus
waitlistStatus, // WaitlistStatus | null
isEntered,
enteredAt, // Date | null
isLoading,
error,
enter, // () => Promise<WaitlistEntry>
leave, // () => Promise<void>
refreshStatus, // () => Promise<WaitlistStatus | null>
} = useWaitlist("waitlist_123", "sequence_456");
useTimedRelease
const {
timedRelease, // TimedRelease details
status, // UseTimedReleaseClientStatus
consumerState, // TimedReleaseConsumerState | null
endTime, // Date | null
timeRemaining, // number | null
isEntered,
hasCompleted,
isLoading,
error,
enter, // (variantId?) => Promise<TimedReleaseConsumerState>
leave, // () => Promise<void>
complete, // () => Promise<void>
refreshStatus, // () => Promise<TimedReleaseConsumerState | null>
} = useTimedRelease("tr_123");
useExperienceJourney
const {
journey, // ExperienceJourney | null
state, // ExperienceJourneyState | null
status, // ExperienceJourneyStatus
error, // string | null
start, // (options?) => Promise<ExperienceJourneyState>
} = useExperienceJourney("exp_123", { autoStart: true });
State Types
Client Status Types
Each hook uses a client-friendly status enum:
// useDraw
type UseDrawClientStatus =
| "idle"
| "not_entered"
| "entered"
| "won"
| "completed"
| "denied"
| "expired"
| "loading"
| "error";
// useAuction
type UseAuctionClientStatus =
| "idle"
| "open"
| "watching"
| "winning"
| "outbid"
| "won"
| "lost"
| "ended"
| "loading"
| "error";
// useWaitlist
type UseWaitlistClientStatus = "idle" | "available" | "entered" | "loading" | "error";
// useTimedRelease
type UseTimedReleaseClientStatus =
| "idle"
| "open"
| "entered"
| "completed"
| "left"
| "expired"
| "ended"
| "loading"
| "error";
// useExperienceJourney
type ExperienceJourneyStatus =
| "idle"
| "entering_experience"
| "routing_sequence"
| "needs_authentication"
| "needs_access_code"
| "validating_access"
| "loading_distributions"
| "entering_waitlist"
| "waiting"
| "ready"
| "no_sequence_available"
| "error";
Hook Dependencies
Hooks depend on the SDK instance from context:
FanfareProvider
└── FanfareContext (SDK instance)
│
├── useFanfare() → SDK
├── useFanfareAuth() → SDK.auth
├── useQueue() → SDK.queues
├── useDraw() → SDK.draws
├── useAuction() → SDK.auctions
├── useWaitlist() → SDK.waitlists
├── useTimedRelease() → SDK.timedReleases
└── useExperienceJourney() → SDK.experiences
Event Subscriptions
Hooks automatically subscribe to relevant SDK events:
// useQueue subscribes to:
// - queue:position-changed
// - queue:admitted
// useDraw subscribes to:
// - draw:entered
// - draw:won
// - draw:lost
// - draw:expired
// - draw:status-updated
// - draw:error
// useAuction subscribes to:
// - auction:entered
// - auction:bid-placed
// - auction:outbid
// - auction:winning
// - auction:won
// - auction:lost
// - auction:left
// - auction:status-updated
// - auction:bid-updated
// - auction:auto-rebid-enabled
// - auction:auto-rebid-disabled
// - auction:error
Cleanup
All hooks properly clean up on unmount:
- Event subscriptions are removed
- Polling is stopped (where applicable)
- Scheduled checks are cancelled
function QueueComponent({ queueId }: { queueId: string }) {
// When this component unmounts, all subscriptions are cleaned up
const { enter, leave } = useQueue(queueId);
return <button onClick={enter}>Enter</button>;
}