MenuClose

Block Newsletter — React Page Block

Newsletter signup that is a working form, not a mockup: client-side validation with inline announced errors, and a confirmation panel on success. Wire onSubscribe; without it, demo mode says so on screen.

View source
PreviewReact
Starting live preview

Usage

import { BlockNewsletter } from "@/components/BlockNewsletter";

export function Signup() {
  return (
    <BlockNewsletter
      title="One careful email a month."
      onSubscribe={async (email) => {
        await fetch("/api/subscribe", { method: "POST", body: JSON.stringify({ email }) });
      }}
      {...{
        title: "One careful email a month.",
        submitLabel: "Subscribe",
        accent: "#d5ed9a",
        scheme: "dark"
      }}
    />
  );
}
Implementation notes & API

Purpose: newsletter signup form. Copy it, ship it — every string, link and color arrives through props. Runtime: pure DOM + CSS. No WebGPU, canvas, animation library or external assets; SSR-safe on first render. Theming: root custom properties (--vb-bg, --vb-fg, --vb-accent, --vb-border, --vb-radius, --vb-container) or the accent/scheme/className/style props. scheme flips the dark default to light. Guardrails: responsive via container queries down to 320px; interactive behavior degrades on touch; prefers-reduced-motion drops entrance/scroll motion while content stays complete. Errors are aria-invalid + role=alert; success swaps to a role=status confirmation. Demo mode validates and confirms locally without sending anything.

PropertyTypeNotes / default
eyebrow / title / descriptionReactNodeSection header
emailLabel / placeholder / submitLabelstringForm copy
onSubscribe(email: string) => void | Promise<void>Your handler; absent = local demo mode
invalidEmailMessage / successTitle / successNote / resetLabelReactNodeValidation and confirmation copy
demoNoteReactNode | nullDemo-mode marker; pass null once wired
scheme"dark" | "light"dark
accentstring (hex)Sets --vb-accent for the whole block
className / stylestring / CSSPropertiesApplied to the section root
childrenReactNodeReplaces the default content entirely
View source on GitHubFree for commercial projects · MIT