# Email Signup Hero

> Minimal centered hero with inline email input field and submit button for newsletter or waitlist signups. Perfect for coming-soon pages and early access campaigns.

A shadcn/ui block from the [@beste-ui](https://ui.beste.co) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/beste-ui/hero69).

- Page, with a live preview: https://shadcn.exchange/r/beste-ui/hero69
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/beste-ui/hero69-light-e89d456623892a92.png
- Registry item: https://ui.beste.co/r/hero69.json
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://ui.beste.co/r/hero69.json
```

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

## Dependencies

- npm packages: `clsx`, `lucide-react`, `tailwind-merge`
- Registry items: `badge`, `button`, `input`

## Files

### `registry/hero69/hero69.tsx`

```tsx
"use client";

import { ArrowRight, Mail } from "lucide-react";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { cn } from "@/lib/utils";

interface Hero69Props {
  badge?: {
    label: string;
    variant?: "default" | "secondary" | "outline";
  };
  heading?: string;
  description?: string;
  inputPlaceholder?: string;
  buttonLabel?: string;
  privacyText?: string;
  className?: string;
}

export const hero69Demo: Hero69Props = {
  badge: { label: "Coming Soon", variant: "secondary" },
  heading: "Be the first to know",
  description:
    "We're building something amazing. Sign up to get early access and exclusive updates.",
  inputPlaceholder: "Enter your email",
  buttonLabel: "Get Early Access",
  privacyText: "We respect your privacy. Unsubscribe at any time.",
};

export function Hero69({
  badge,
  heading,
  description,
  inputPlaceholder,
  buttonLabel,
  privacyText,
  className,
}: Hero69Props) {
  return (
    <section className={cn("py-16 md:py-24 w-full", className)}>
      <div className="mx-auto max-w-3xl px-4 md:px-6">
        <div className="flex flex-col items-center text-center">
          {badge && (
            <Badge variant={badge.variant ?? "default"} className="mb-6">
              {badge.label}
            </Badge>
          )}

          {heading && (
            <h1 className="text-4xl font-bold tracking-tight md:text-5xl lg:text-6xl">
              {heading}
            </h1>
          )}

          {description && (
            <p className="mt-6 max-w-xl text-lg text-muted-foreground">
              {description}
            </p>
          )}

          <form
            className="mt-10 flex w-full max-w-md flex-col gap-3 sm:flex-row"
            onSubmit={(e) => e.preventDefault()}
          >
            <div className="relative flex-1">
              <Mail className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
              <Input
                type="email"
                placeholder={inputPlaceholder}
                className="h-10 pl-9"
              />
            </div>
            <Button type="submit" size="lg" className="h-10">
              {buttonLabel}
              <ArrowRight className="size-4" />
            </Button>
          </form>

          {privacyText && (
            <p className="mt-4 text-sm text-muted-foreground">{privacyText}</p>
          )}
        </div>
      </div>
    </section>
  );
}
```
