taldres/laravel-waitlist
taldres/laravel-waitlist is a lightweight Laravel package for adding a waitlist to your app. Let users join, store signups, verify emails, and manage entries with configurable models, migrations, and routes—ideal for launching products with early-access queues.
->publicCount() and ->publicPosition() let product/marketing show demand (“joined by 240 people”, “you’re #37”) without exposing subscriber emails. The privacy defaults matter for roadmap decisions: off by default, rounded down to ten, null below ten, and unavailable on lists without double opt-in.retention.reconfirm_after_days plus reconfirm_within_days turns the waitlist into a re-permissioning tool. This supports roadmap decisions around re-engagement, dormant-subscriber cleanup, and “lapsed” lifecycle states before launch.waitlist:import / Waitlist::for($list)->import() keeps consent provenance (EntryImported with original consent time for confirmed imports), which is directly useful for legal/compliance review and for deciding whether to migrate from spreadsheet, Typeform, Mailchimp, or an older waitlist.TimeTrapSpamProtector (hidden field + time trap) is a build-vs-buy decision point: it removes the need for reCAPTCHA/hCaptcha for basic form protection, at the cost of weaker protection than dedicated services.PublishableKeyResolver maps X-Waitlist-Key to a project, supporting product decisions around embeddable or multi-brand waitlist pages without exposing admin credentials.--isolated command options, terminal prompts for missing arguments, waitlist:install --mail, and the new referral example support decisions to run the waitlist in production with scheduled jobs and safe concurrent deployments.Consider it when:
Look elsewhere or defer when:
LinkGenerator classes, removed Waitlist::verifySpamUsing() / spamProtector(), ListPolicy::doubleOptIn() method, #[UseFactory] requirement for extended models, new enum cases, and GET/POST split mail routes).@taldres/laravel-waitlist 0.1.x and cannot upgrade to 0.2.0: earlier JS clients do not read count, position, challenge, or answer_by, and the release explicitly warns not to enable reconfirmation or TimeTrapSpamProtector on such pages.waitlist_wordings.project values longer than 100 characters. The new widen_waitlist_wordings_table migration shrinks the column to 100 and fails if longer names are stored; this must be cleaned up before upgrading.To executives: This release turns the waitlist from a simple signup form into a launch-readiness tool. We can show social proof safely, import existing demand with consent records, re-confirm dormant subscribers before launch, and add basic bot protection without buying another SaaS product. That reduces vendor spend and time-to-market while keeping subscriber data in our own Laravel app.
To engineering: The package now aligns with Laravel 13 conventions and adds operational commands, import/export, retention flows, and a pluggable spam protector. The trade-off is a real upgrade task: renamed classes, removed spam binding methods, route method splits for confirm/unsubscribe links, new enum cases, factory attributes on extended models, and two new migrations. The JS client must be on 0.2.0 for count/position/challenge features, and MySQL/MariaDB project names must fit 100 characters before migration.
To marketing/growth: We can publish rounded waitlist counts and individual place-in-line, import existing subscribers, and run reconfirmation campaigns to keep the list healthy. Referral examples and wording/version fields support campaign iteration, but public count/position must stay off for lists without double opt-in and are off by default.
To legal/privacy: Consent provenance is improved through import tracking and explicit reconfirmation/lapse states. Public count and position features are constrained: counts are rounded down and hidden below ten, position is token-based rather than address-based, and both require list opt-in. These defaults support a privacy review rather than bypassing it.
How can I help you explore Laravel packages today?