# Newsletter Subscription

> A newsletter subscription form in a dialog.

A shadcn/ui block from the [@buzzform](https://form.buildnbuzz.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/buzzform/newsletter-dialog).

- Page, with a live preview: https://shadcn.exchange/r/buzzform/newsletter-dialog
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/buzzform/newsletter-dialog-light-74db4e683ce2c2bc.png
- Registry item: https://form.buildnbuzz.com/r/newsletter-dialog.json
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://form.buildnbuzz.com/r/newsletter-dialog.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- Registry items: `@buzzform/email`, `@buzzform/checkbox`, `dialog`, `button`, `sonner`

## Files

### `registry/shadcn/examples/newsletter-dialog.tsx`

```tsx
"use client";

import { useState } from "react";
import { toast } from "sonner";
import { defineSchema, type InferType } from "@buildnbuzz/form-react";
import {
  Form,
  FormContent,
  FormFields,
  FormSubmit,
} from "@/registry/shadcn/form";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";

// Newsletter subscription with checkbox consent
const newsletterSchema = defineSchema({
  fields: [
    {
      type: "email",
      name: "email",
      label: "Email Address",
      placeholder: "you@example.com",
      required: true,
    },
    {
      type: "checkbox",
      name: "consent",
      label: "I agree to receive marketing emails and can unsubscribe anytime.",
      required: true,
    },
  ],
});

type NewsletterSchema = InferType<typeof newsletterSchema.fields>;

export default function NewsletterDialogExample() {
  const [open, setOpen] = useState(false);

  const handleSubmit = async ({ value }: { value: unknown }) => {
    const data = value as NewsletterSchema;
    await new Promise((resolve) => setTimeout(resolve, 800));
    toast("Subscribed!", {
      description: (
        <pre className="mt-2 max-h-48 overflow-auto rounded-md bg-muted text-muted-foreground p-3 text-xs">
          <code>{JSON.stringify(data, null, 2)}</code>
        </pre>
      ),
    });
    setOpen(false);
  };

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogTrigger render={<Button variant="outline" />}>
        Subscribe to Newsletter
      </DialogTrigger>
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <DialogTitle>Stay Updated</DialogTitle>
          <DialogDescription>
            Get the latest BuzzForm updates, tips, and new feature
            announcements.
          </DialogDescription>
        </DialogHeader>
        <Form schema={newsletterSchema} onSubmit={handleSubmit}>
          <FormContent className="space-y-4">
            <FormFields />
            <FormSubmit className="w-full">Subscribe</FormSubmit>
          </FormContent>
        </Form>
      </DialogContent>
    </Dialog>
  );
}
```
