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.
Waitlist Widget
The Waitlist Widget provides a pre-registration experience for consumers to sign up before a distribution opens, with countdown display and notification signup.
Web Component
<fanfare-waitlist-widget waitlist-id="waitlist_123" show-header="true" show-countdown="true" show-actions="true" />
Attributes
| Attribute | Type | Default | Description |
|---|
waitlist-id | string | Required | The waitlist identifier |
show-header | string | "true" | Show title and description |
show-countdown | string | "true" | Show countdown to open |
show-actions | string | "true" | Show join/leave buttons |
container-class | string | - | Custom CSS class for container |
Events
| Event | Detail | Description |
|---|
fanfare-waitlist-enter | { waitlistId: string } | User joined waitlist |
fanfare-waitlist-leave | { waitlistId: string } | User left waitlist |
fanfare-waitlist-open | { waitlistId: string } | Waitlist period opened |
fanfare-waitlist-proceed | { waitlistId: string } | User proceeding |
Event Handling Example
import { useEffect, useRef } from "react";
function WaitlistPage() {
const widgetRef = useRef<HTMLElement>(null);
useEffect(() => {
const widget = widgetRef.current;
if (!widget) return;
const handleEnter = (e: CustomEvent) => {
console.log("Joined waitlist:", e.detail.waitlistId);
analytics.track("waitlist_joined");
showSuccessToast("You are on the waitlist! We will notify you when it opens.");
};
const handleOpen = (e: CustomEvent) => {
console.log("Waitlist opened!");
// Redirect to the main experience
window.location.href = `/experience/${e.detail.waitlistId}`;
};
widget.addEventListener("fanfare-waitlist-enter", handleEnter);
widget.addEventListener("fanfare-waitlist-open", handleOpen);
return () => {
widget.removeEventListener("fanfare-waitlist-enter", handleEnter);
widget.removeEventListener("fanfare-waitlist-open", handleOpen);
};
}, []);
return (
<div className="waitlist-container">
<h1>Coming Soon</h1>
<p>Sign up to be notified when we launch!</p>
<fanfare-waitlist-widget ref={widgetRef} waitlist-id="waitlist_123" />
</div>
);
}
Waitlist Status States
The widget handles these waitlist states automatically:
| Status | Description | UI Display |
|---|
available | Waitlist is open for signup | Join button + Countdown |
entered | User is on the waitlist | Confirmation + Countdown |
opening | About to open (< 1 minute) | Urgent countdown |
opened | Distribution is now open | Proceed CTA |
Styling
CSS Variables
fanfare-waitlist-widget {
--fanfare-primary: #8b5cf6;
--fanfare-primary-hover: #7c3aed;
--fanfare-success: #22c55e;
--fanfare-background: #ffffff;
--fanfare-foreground: #1f2937;
--fanfare-muted: #f3f4f6;
--fanfare-radius: 0.75rem;
}
Product Launch Page Example
function ProductLaunchPage() {
const widgetRef = useRef<HTMLElement>(null);
const [isOnWaitlist, setIsOnWaitlist] = useState(false);
useEffect(() => {
const widget = widgetRef.current;
if (!widget) return;
const handleEnter = () => {
setIsOnWaitlist(true);
};
const handleLeave = () => {
setIsOnWaitlist(false);
};
widget.addEventListener("fanfare-waitlist-enter", handleEnter);
widget.addEventListener("fanfare-waitlist-leave", handleLeave);
return () => {
widget.removeEventListener("fanfare-waitlist-enter", handleEnter);
widget.removeEventListener("fanfare-waitlist-leave", handleLeave);
};
}, []);
return (
<div className="product-launch">
<div className="hero">
<img src="/product-teaser.jpg" alt="New Product" />
<h1>Exclusive Limited Edition Drop</h1>
<p>Only 100 units available worldwide</p>
</div>
<div className="waitlist-section">
<fanfare-waitlist-widget ref={widgetRef} waitlist-id="waitlist_123" />
{isOnWaitlist && (
<div className="confirmation">
<p>Check your email for confirmation!</p>
</div>
)}
</div>
<div className="features">
<h2>Why Join the Waitlist?</h2>
<ul>
<li>Early access notification</li>
<li>Priority checkout window</li>
<li>Exclusive updates</li>
</ul>
</div>
</div>
);
}
Using with React Hook (Alternative)
For more control, use the useWaitlist hook:
import { useWaitlist } from "@waitify-io/fanfare-sdk-react";
function CustomWaitlistUI() {
const { waitlist, status, opensAt, timeUntilOpen, isEntered, enter, leave, isLoading } = useWaitlist("waitlist_123");
if (status === "opened") {
return (
<div className="opened">
<h2>It is Open!</h2>
<a href="/shop">Start Shopping</a>
</div>
);
}
return (
<div className="waitlist-ui">
{opensAt && (
<div className="countdown">
<p>Opens in:</p>
<span className="time">{formatCountdown(timeUntilOpen)}</span>
</div>
)}
{isEntered ? (
<div className="entered">
<p>You are on the waitlist!</p>
<p>We will notify you when it opens.</p>
<button onClick={leave} className="secondary">
Leave Waitlist
</button>
</div>
) : (
<button onClick={enter} disabled={isLoading}>
{isLoading ? "Joining..." : "Join Waitlist"}
</button>
)}
</div>
);
}
TypeScript Declaration
declare namespace JSX {
interface IntrinsicElements {
"fanfare-waitlist-widget": React.DetailedHTMLProps<
React.HTMLAttributes<HTMLElement> & {
"waitlist-id": string;
"show-header"?: string;
"show-countdown"?: string;
"show-actions"?: string;
"container-class"?: string;
},
HTMLElement
>;
}
}