Newsletter Signup
A newsletter signup is a small <form> composition that collects an email address for subscription. It supports four explicit states — idle, submitting, success, and error — surfaced as data-state and reflected in the input/button disabled state and live-region messages.
Use it in marketing footers, blog sidebars, splash pages, and dedicated subscription landing pages.
Implementation Notes
- Uses a native
<form>element witharia-labeldescribing the form's purpose stateis exposed asdata-stateand gatesdisabledon the email input and submit button (when "submitting")- Success message uses
role="status"+aria-live="polite"so screen readers announce non-disruptive confirmation - Error message uses
role="alert"so screen readers announce errors immediately - Both messages are conditionally
hiddenbased onstate - All visible strings (heading, description, email label, submit label, success/error) are provided as props for i18n
- Submit handling is delegated to the consumer via
onSubmit/onsubmit
Props
label: string (required) -- aria-label for the formheading: string (optional) -- visible headingdescription: string (optional) -- body text below the headingemailLabel: string (required) -- visible label for the email inputemailPlaceholder: string (optional)submitLabel: string (required) -- submit button textstate: "idle" | "submitting" | "success" | "error" (default: "idle")successMessage: string (optional) -- confirmation message when state is "success"errorMessage: string (optional) -- error message when state is "error"onSubmit/onsubmit: callback (optional) -- submit handler...restProps: any additional HTML attributes
Usage
Idle state with heading and description:
<NewsletterSignup
label="Subscribe to the newsletter"
heading="Stay in the loop"
description="One email per week, no spam."
emailLabel="Email address"
submitLabel="Subscribe"
onsubmit={handleSubmit}
/>
Success state:
<NewsletterSignup
label="Subscribe to the newsletter"
emailLabel="Email address"
submitLabel="Subscribe"
state="success"
successMessage="Thanks! Please check your inbox to confirm."
/>
Keyboard Interactions
- Tab: Move focus through the email input and submit button
- Enter inside the email input: Submit the form
- (All handled natively by
<form>,<input>, and<button>)
ARIA
aria-labelon the<form>provides the form's accessible namedata-statereflects the current state ("idle" | "submitting" | "success" | "error")- Email input and submit button are
disabledwhen state is "submitting" - Success message:
role="status"+aria-live="polite"(non-disruptive) - Error message:
role="alert"(immediately announced) - Both messages use
hiddenwhen not in their corresponding state
When to Use
- Use to collect newsletter subscriptions in marketing surfaces.
- Use whenever you need an explicit submit/loading/success/error progression for a single email field.
When Not to Use
- Do not use for multi-field signup or registration flows — use Form with multiple Field components.
- Do not use for in-app notification preferences — use a settings UI.
Headless
Renders a <form> with <label> + <input type="email"> + <button type="submit">, plus conditional success/error message paragraphs. Visual styling, layout direction (row/column), inline placement of messages, and submit logic are the consumer's responsibility.
Styles
Consumer CSS targets the newsletter-signup class on the form. Use the data-state attribute selector to style the form per state. Style the inner newsletter-signup-success and newsletter-signup-error classes for status messaging.
Testing
- Verify the component renders a
<form>element with classnewsletter-signup - Verify
aria-labelis present and equals thelabelprop - Verify
data-statereflects thestateprop - Verify the email input and submit button are
disabledwhen state is "submitting" - Verify the success message renders with
role="status"+aria-live="polite"and is hidden unless state is "success" - Verify the error message renders with
role="alert"and is hidden unless state is "error" - Verify the submit handler fires on form submission
Advice
- Designers: Use a clear, single-line layout where possible. Reserve vertical space for the success and error messages so the layout does not jump.
- Developers: Always supply
label,emailLabel, andsubmitLabel(required). Do not announce success withrole="alert"— that is reserved for errors. Disable the submit while submitting to avoid duplicate calls.
Related components
form— a form element for collecting and submitting user dataemail-input— an input for entering an email address <input type="email">call-to-action— a prominent prompt encouraging user action
References
- WAI-ARIA
role="status": https://www.w3.org/TR/wai-aria-1.2/#status - WAI-ARIA
role="alert": https://www.w3.org/TR/wai-aria-1.2/#alert - MDN
aria-live: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-live - Mozilla Protocol Design System: https://protocol.mozilla.org/