Skip to main content
← All notes
Building

The newsletter catches bots before they subscribe

softwareaccessibility

The newsletter signup sits at the bottom of the homepage in a glass card. One email input, one subscribe button, one honeypot. The honeypot is an invisible text field named website with aria-hidden true and tabIndex negative one. A real user never sees it. A bot filling out every field on the page fills it in. When the API receives a request where the website field has a value, it returns success true without doing anything. No error message, no feedback, nothing for the bot to learn from. It thinks it subscribed. It did not. For real subscribers, the API adds the email to a Resend Audience using the contacts.create endpoint. If the contact already exists — the API returns an error message containing already exists — the handler catches it and returns alreadySubscribed true instead of treating it as a failure. The component reads that flag and shows You're already subscribed instead of the generic success message. For new subscribers, the API sends a welcome email immediately after the contact is created. The email is plain text — a greeting, a one-sentence description of what to expect, and a sign-off. No HTML template, no images, no tracking pixels. The component handles four states — idle, loading, success, and error. The loading state disables the button and shows three dots. The success state replaces the entire form with the confirmation message so there is no way to accidentally double-subscribe. One form, one honeypot, one Audience, one welcome email, four states.

Comments coming soon

Sign in with TikTok to leave a comment. Coming soon.