Newsletter Signup
The newsletter at the foot of a page: a title, a line, an email field with its label and Subscribe. It checks before it sends and says what happened.
Preview
Usage
import { NewsletterSignup } from "zostel-ui";
<NewsletterSignup
action="/api/newsletter"
onSubscribe={async (email) => {
await fetch("/api/newsletter", { method: "POST", body: JSON.stringify({ email }) });
}}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
onSubscribe | (email: string) => void | Promise<void> | — | Required: called with a valid address (without it nothing is sent, so it could never honestly say you’re in). A promise shows “Sending…”, with the field read-only and Subscribe aria-disabled, so the focus stays; a rejection says it didn’t go through and puts the focus back in the field. |
action · method | string · string | — · "post" | Where the form posts before the script runs, or without it. method is post, so the address goes in the request’s body, never into the page’s URL. |
titleAs | "h2" | "h3" | "h4" | "p" | "h3" | The title’s element, so it sits in the page’s outline. |
title · body | ReactNode | — | The heading and the line beside the field. |
buttonLabel | string | "Subscribe" | The button’s word. |
doneMessage | ReactNode | "You're in. Watch your inbox." | What it says once you’re in. |
className | string | — | More classes, merged with the component’s own (tailwind-merge). |
onSubscribe(email: string) => void | Promise<void>Required: called with a valid address (without it nothing is sent, so it could never honestly say you’re in). A promise shows “Sending…”, with the field read-only and Subscribe aria-disabled, so the focus stays; a rejection says it didn’t go through and puts the focus back in the field.
action · methodstring · string— · "post"Where the form posts before the script runs, or without it. method is post, so the address goes in the request’s body, never into the page’s URL.
titleAs"h2" | "h3" | "h4" | "p""h3"The title’s element, so it sits in the page’s outline.
title · bodyReactNodeThe heading and the line beside the field.
buttonLabelstring"Subscribe"The button’s word.
doneMessageReactNode"You're in. Watch your inbox."What it says once you’re in.
classNamestringMore classes, merged with the component’s own (tailwind-merge).
On zostel.com
Above the footer of every page. The field has a real label, a wrong address is said in words next to it (not only in red), and the status lives in a polite live region.