Newsletter Signup Section React component
A newsletter signup section: perks and reader proof on the left, a form card with email validation, weekly or monthly radio cards and topic chips on the right, a check-your-inbox screen with a resend cooldown, and a list of recent issues.
About the Newsletter Signup Section component
Newsletter Signup Section is a full signup block rather than a single input. The left column sells the newsletter with a title, a short description, a few perks and a line of reader proof; the right column is a form card with the email field, a choice of how often (weekly or monthly) and topic chips, so you can segment from day one.
The email is checked when people leave the field or press Subscribe. While your onSubscribe promise runs the button shows a spinner; a rejection or a returned string appears above it, and success switches to a check-your-inbox screen with a resend link that waits 30 seconds between tries. Recent issues can be listed under the card.
When to use it
Use it at the bottom of a blog, a docs site or a product landing page, or as the main section of a newsletter page.
Connect onSubscribe to your email platform (ConvertKit, Beehiiv, Mailchimp, Resend Audiences) through an API route.
Installation
Add the Newsletter Signup Section component to your project with the shadcn CLI. It lands in components/newsletter-signup-section.tsx as plain React + Tailwind CSS source you own and can edit.
npx shadcn@latest add @reactframe/newsletter-signup-sectionOr copy the source by hand and install its dependencies:
npm install motion clsx tailwind-mergeProps
<NewsletterSignupSection /> accepts 14 props, all optional.
| Prop | Type | Default |
|---|---|---|
| eyebrow | string | "Newsletter" |
| title | string | "The Thursday letter for people who build products" |
| description | string | "One email a week with what we learned shipping software: planning, specs, design reviews… |
| perks | string[] | DEFAULT_PERKS |
| frequencies Radio cards for how often people get the email. Pass [] to hide them. | { id: string; label: string; note?: string }[] | DEFAULT_FREQUENCIES |
| topics Topic chips people can pick from. Pass [] to hide them. | string[] | DEFAULT_TOPICS |
| issues Recent issues listed under the form. Pass [] to hide them. | { title: string; date: string; href?: string }[] | DEFAULT_ISSUES |
| proof Social proof under the perks. Pass null to hide it. | { avatars?: string[]; text: string } | null | { avatars: ["/demo/41.webp", "/demo/44.webp", "/demo/42.webp"], text: "Join 24,000 reader… |
| onSubscribe Called with the email, frequency and topics. Return a promise: the button spins while it runs, a rejection (or a returned string) shows an error, and success shows the check-your-inbox screen. | (data: NewsletterSubscribeData) => void | string | Promise<void | string> | — |
| onResend Called from the success screen's resend link. | (email: string) => void | — |
| submitLabel | string | "Subscribe" |
| privacyNote | React.ReactNode | "No spam. We never share your email." |
- eyebrowstringDefault: "Newsletter"
- titlestringDefault: "The Thursday letter for people who build products"
- descriptionstringDefault: "One email a week with what we learned shipping software: planning, specs, design reviews…
- perksstring[]Default: DEFAULT_PERKS
- frequencies
Radio cards for how often people get the email. Pass [] to hide them.
{ id: string; label: string; note?: string }[]Default: DEFAULT_FREQUENCIES - topics
Topic chips people can pick from. Pass [] to hide them.
string[]Default: DEFAULT_TOPICS - issues
Recent issues listed under the form. Pass [] to hide them.
{ title: string; date: string; href?: string }[]Default: DEFAULT_ISSUES - proof
Social proof under the perks. Pass null to hide it.
{ avatars?: string[]; text: string } | nullDefault: { avatars: ["/demo/41.webp", "/demo/44.webp", "/demo/42.webp"], text: "Join 24,000 reader… - onSubscribe
Called with the email, frequency and topics. Return a promise: the button spins while it runs, a rejection (or a returned string) shows an error, and success shows the check-your-inbox screen.
(data: NewsletterSubscribeData) => void | string | Promise<void | string> - onResend
Called from the success screen's resend link.
(email: string) => void - submitLabelstringDefault: "Subscribe"
- privacyNoteReact.ReactNodeDefault: "No spam. We never share your email."
Show all 14 propsShow fewer
| theme | "dark" | "light" | "dark" |
| className | string | — |
- theme"dark" | "light"Default: "dark"
- classNamestring
npm dependencies
Installed for you by the shadcn CLI.
Newsletter Signup Section FAQ
- How do I connect it to my email provider?
- Handle onSubscribe and post { email, frequency, topics } to an API route that calls your provider, for example ConvertKit, Beehiiv, Mailchimp or Resend. Throw an Error with a message if it fails and the form shows it.
- Does it support double opt-in?
- The success screen already says to check the inbox for a confirmation link and offers a resend. Pass onResend to send the confirmation again; the link then waits 30 seconds before it can be used again.
- Can I make it a simple email-only form?
- Yes. Pass frequencies={[]}, topics={[]} and issues={[]} and the card becomes just the email field and button. perks={[]} and proof={null} slim down the left column.
- Where do topics go?
- The chosen topics are sent as an array in onSubscribe, so you can map them to tags or groups in your email tool. The first two are selected by default.
- Is it accessible?
- The email has a label and autocomplete, invalid input sets aria-invalid and an alert, the frequency and topic options are real radio and checkbox inputs with visible focus rings, and focus moves to the success heading.