Build a custom waitlist form
Clerk's <Waitlist /> component provides an out-of-the-box solution for allowing users to join your waitlist for early access to your app. However, if you're building a custom user interface, you can use the useWaitlist() hook to build a custom waitlist form.
This guide demonstrates how to use the Clerk API to build a custom user interface for joining your app's waitlist.
Before you start
Before using the useWaitlist() hook, you must enable Waitlist mode in the Clerk Dashboard:
- In the Clerk Dashboard, navigate to the Waitlist page.
- Toggle on Enable waitlist and select Save.
Build the custom flow
The following example demonstrates how to use the useWaitlist() hook to create a custom waitlist form. Users can submit their email address to join the waitlist, and the component displays appropriate feedback based on the submission state.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/clerk.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Clerk + JavaScript App</title>
</head>
<body>
<div id="success-message" style="display: none">
<h1>Successfully joined the waitlist!</h1>
<p>We'll notify you when you're approved.</p>
</div>
<div id="waitlist-form-container">
<h1>Join the Waitlist</h1>
<form id="waitlist-form">
<label for="email">Email address</label>
<input id="email" name="emailAddress" type="email" required />
<p id="error" style="color: red"></p>
<button type="submit">Join Waitlist</button>
</form>
</div>
<script type="module" src="main.js" async crossorigin="anonymous"></script>
</body>
</html>import { Clerk } from '@clerk/clerk-js'
const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY
const clerk = new Clerk(pubKey)
await clerk.load()
const successMessage = document.getElementById('success-message')
const formContainer = document.getElementById('waitlist-form-container')
const form = document.getElementById('waitlist-form')
const errorElement = document.getElementById('error')
// Check if user has already joined the waitlist
if (clerk.waitlist?.id) {
successMessage.style.display = 'block'
formContainer.style.display = 'none'
} else {
form.addEventListener('submit', async (e) => {
e.preventDefault()
const formData = new FormData(e.target)
const emailAddress = formData.get('emailAddress')
try {
await clerk.waitlist.join({ emailAddress })
// Show success message
successMessage.style.display = 'block'
formContainer.style.display = 'none'
} catch (error) {
// Display error message
errorElement.textContent = error.errors?.[0]?.longMessage || 'Failed to join waitlist'
}
})
}Feedback
Last updated on