Components / Blocks
NewsletterSignup
An email signup framed by a stack of past issues; subscribing drops the next issue, addressed to you, onto the front.
Install
npx shadcn@latest add https://irisui.dev/r/newsletter-signup.jsonimport { NewsletterSignup } from "@/components/iris/blocks/newsletter-signup/newsletter-signup";Preview
NewsletterSignup
An email signup framed by a stack of recent issues; subscribing drops the next issue, addressed to the new reader, onto the front of the stack and ticks the reader count up by one.
When to use
- A newsletter or release-notes signup section on a blog, docs or landing page.
inlineas a page section beside the stack;cardas a self-contained card with the stack in a tray on top.- Not for a one-field signup inside a footer: use
SiteFooterwithnewsletter. - Not for account creation: use
SignupForm.
Usage
import { NewsletterSignup } from "@/components/iris/blocks/newsletter-signup/newsletter-signup";
h(NewsletterSignup, {
variant: "inline",
title: "Five minutes on humane work design, every Friday",
description: "One short essay and three notes.",
readers: { count: 1240, faces: [] },
publication: {
name: "Kumbatio notes",
upcoming: {
number: 42,
date: "Friday, 23 Oct",
subject: "Rest is empty, never an alarm",
stories: [{ title: "Deferral as a strategy", image: "/thumbs/1.png", minutes: 4 }],
},
recent: [/* newest first; the first three form the stack */],
},
onSubscribe: (email) => api.subscribe(email), // reject to show an error and keep the email
});
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant |
"inline" | "card" |
"inline" |
Copy and form beside the stack, or a card with the stack on top. |
title / description |
string |
per variant | Heading and supporting text. |
placeholder |
string |
"you@company.com" |
Email field placeholder. |
buttonLabel |
string |
"Subscribe" |
Submit label. |
privacyNote |
ReactNode |
sample line | Short line under the form about frequency and privacy. |
privacyLink |
{ label, href } | null |
Privacy policy | Link after the note. null hides it. |
readers |
{ count, faces: string[] } | null |
1,240 with no faces | Reader count and up to three face URLs. null hides it. |
publication |
NewsletterPublication | null |
"Kumbatio notes" sample | { name, upcoming: Issue, recent: Issue[] }, where an issue is { number, date, subject, stories: { title, image, minutes }[] } (up to three stories, square thumbnails). null gives a form without the stack. |
onSubscribe |
(email: string) => void | Promise<void> |
none | Called with a valid, trimmed email. Reject to show an error; resolve to show success. |
className |
string |
none | Extra class. |
Notes
- The default publication is a sample Kumbatio letter whose thumbnails are flat inline SVG placeholders; the default readers show a count without faces. Pass your own
publicationandreaders. - Validation messages: an empty field asks for an address, a malformed one asks for "name@company.com", a rejected
onSubscribekeeps the email and asks to try again. The field shakes on error unless reduced motion is on. - On success focus moves to the "Use a different email" button, the confirmation names the address for screen readers, and the reader line adds ", including you".