Waitly-SDK v1.0.4 is the latest release of our seamless, developer-friendly waitlist SDK. Built with builders, indie hackers, and modern SaaS teams in mind, it makes embedding a fully functional, customizable waitlist in your JavaScript-based frontend a breeze.
Why you’ll love waitly-sdk v1.0.4:
Fast & efficient: Integrate in under 3 minutes
JavaScript-native: Plug directly into React, Next.js, Vue, Angular, and more
Feature-rich out of the box: Query waitlist counts, submit entries, check email status—all ready
Sleek & modern: Lightweight, well-documented, and optimized for performance
You can find the documentation here: https://www.gowaitly.com/doc
This quick tutorial will show you how to integrate it into a Next.js application.
Getting started: integrating waitly-sdk v1.0.4 in Next.js
1. Install the SDK & Configure Environment Variables
First, install the SDK:
npm install @go-waitly/waitly-sdk Set your environment variables in your .env:
NEXT_PUBLIC_WAITLY_WAITLIST_ID=your_waitlist_id NEXT_PUBLIC_WAITLY_API_KEY=your_api_key These values are typically found in your Waitly dashboard. Using NEXT_PUBLIC_ makes them accessible both server- and client-side.
2. Fetch Waitlist Count (Server-Side)
Create a server-rendered page to show the current number of people in the waitlist, helping to build social proof:
import { Input } from "@/components/ui/input";
import { WaitlistForm } from "@/components/waitlist";
import { createWaitlyClient } from "@go-waitly/waitly-sdk";
import React from "react";
export default async function Waitlist() {
const waitlyClient = createWaitlyClient({
apiKey: "ak_68bbe8607772c56ea877c126579ec9e0",
waitlistId: "62e4f5d3-a590-4dc1-89f9-f0737400cacd",
});
const count = await waitlyClient.getWaitlyEntriesCount();
return (
<div className="flex flex-col items-center justify-center h-screen">
<h1>Waitlist</h1>
<p>
Already {count as number} people on the waitlist. Be the first to know
when we launch.
</p>
<WaitlistForm initialCount={count as number} />
</div>
);
}
This ensures your page is SEO-friendly, using SSR to fetch real-time counts before rendering.
3. Build the Waitlist Form (Client-Side)
Now, create a React component that handles user interactions:
"use client";
import { useState } from "react";
import { createWaitlyClient } from "@go-waitly/waitly-sdk";
interface WaitlistFormProps {
initialCount: number;
}
export function WaitlistForm({ initialCount }: WaitlistFormProps) {
const [email, setEmail] = useState("");
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
const [success, setSuccess] = useState<{ position: number } | null>(null);
const [count, setCount] = useState(initialCount);
const client = createWaitlyClient({
waitlistId: "62e4f5d3-a590-4dc1-89f9-f0737400cacd",
apiKey: "ak_68bbe8607772c56ea877c126579ec9e0",
});
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setError("");
setLoading(true);
try {
const exists = await client.checkEmailExists(email);
const response = await client.createWaitlyEntry({
email,
referredByCode: "123456",
});
setCount(count + 1);
setEmail("");
} catch (error) {
setError(
error instanceof Error ? error.message : "Une erreur est survenue"
);
} finally {
setLoading(false);
}
};
if (success) {
return (
<div className="text-center py-8">
<div className="text-green-600 text-5xl mb-4">✓</div>
<h2 className="text-xl font-semibold mb-2">Success !</h2>
<p className="text-gray-600">You are in position</p>
<p className="text-3xl font-bold text-purple-600 mt-2">
#{success.position}
</p>
<button
onClick={() => setSuccess(null)}
className="mt-6 text-sm text-purple-600 hover:underline"
>
Inscrire une autre personne
</button>
</div>
);
}
return (
<div className="max-w-md mx-auto">
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="votre@email.com"
required
disabled={loading}
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500"
/>
</div>
{error && <div className="text-red-600 text-sm">{error}</div>}
<button
type="submit"
disabled={loading}
className="w-full py-3 bg-purple-600 text-white rounded-lg font-medium hover:bg-purple-700 disabled:opacity-50 disabled:cursor-not-allowed"
>
{loading ? "Checking..." : "Join the waitlist"}
</button>
<p className="text-center text-sm text-gray-500">
{count} people in the waitlist
</p>
</form>
</div>
);
}
This component uses the SDK to check email duplicates and submit new entries, then updates the UI with the user's waitlist position and entry count

