Xzero UI
Pro library

Newsletter signup

An email signup framed by a stack of past issues; subscribing drops the next issue, addressed to you, onto the front.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui/newsletter-signup
Live · keyboard ready

Use this to collect newsletter or waitlist emails. Pass onSubscribe to call your email provider and throw on failure; subscribing in the preview is simulated.

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui/newsletter-signup

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { NewsletterSignup } from "@/components/xzero/blocks/newsletter-signup/newsletter-signup";

export function Newsletter() {
  return (
    <NewsletterSignup
      variant="card"
      onSubscribe={async email => {
        const response = await fetch("/api/subscribe", { method: "POST", body: JSON.stringify({ email }) });
        if (!response.ok) throw new Error("Subscribe failed");
      }}
    />
  );
}

API reference

NewsletterSignup

A newsletter signup framed by the newsletter itself: a stack of recent issues. Subscribing drops the next issue, addressed to the new reader, onto the front of the stack. Inline section or card.

PropTypeDefaultDescription
variant"inline" | "card""inline"inline puts the copy and form beside the issue stack; card is a self-contained card with the stack in a tray on top.
titlestring–Heading. Each variant has sample copy.
descriptionstring–One sentence on what people get and how often.
placeholderstring"you@company.com"Email field placeholder.
buttonLabelstring"Subscribe"Submit button label.
privacyNoteReactNode"No tracking pixels. Unsubscribe with one click."Line under the form about frequency and privacy.
privacyLink{ label: string; href: string } | null–Link after the note. Pass null to hide it.
publicationNewsletterPublication | null–The issue stack: { name, upcoming, recent }. Each issue has a number, a date, a subject, and up to three stories with a thumbnail and read time. Pass null for the form alone.
readers{ count: number; faces: string[] } | null–Reader count and up to three faces, under the stack or at the foot of the card. The count ticks up by one on success. Pass null to hide.
onSubscribe(email: string) => void | Promise<void>–Called with a valid, trimmed email. Resolve to show success; reject to show an error and keep the email.
classNamestring–Extra class on the section.

Keyboard interactions

KeysAction
EnterIn the email field, submits the form. The phone keyboard shows a send key.
TabMoves from the field to the button, the privacy link, and after success to "Use a different email".

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Guidance for AI tools

Blocks are complete, self-contained screens with sample data. Replace the sample data and connect the callbacks described above. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components