Ready to get started?
Join thousands of teams already using our platform to build better products.
Join our community
Connect with thousands of developers building amazing products.
Installation
Copy and paste the following code into your project.
"use client";
import { Button } from "@/components/ui/button";
import { ArrowRight } from "lucide-react";
interface CTABannerSimpleProps {
headline: string;
description?: string;
variant?: "default" | "primary" | "dark";
primaryCTA: {
text: string;
href?: string;
onClick?: () => void;
};
secondaryCTA?: {
text: string;
href?: string;
onClick?: () => void;
};
}
const variants = {
default: {
section: "bg-muted/30",
headline: "text-foreground",
description: "text-muted-foreground",
primaryButton: "",
secondaryButton: "",
},
dark: {
section: "bg-slate-950",
headline: "text-white",
description: "text-slate-400",
primaryButton: "bg-white text-slate-950 hover:bg-slate-100",
secondaryButton:
"border-slate-700 text-white hover:bg-slate-900 hover:text-white",
},
};
export function CTABannerSimple({
headline,
description,
variant = "default",
primaryCTA,
secondaryCTA,
}: CTABannerSimpleProps) {
const styles = variants[variant];
return (
<section
className={`relative overflow-hidden py-16 sm:py-20 ${styles.section}`}
>
{/* Grid pattern */}
<div className="absolute inset-0 -z-10 bg-[linear-gradient(to_right,#80808008_1px,transparent_1px),linear-gradient(to_bottom,#80808008_1px,transparent_1px)] bg-[size:24px_24px]" />
<div className="container mx-auto px-6">
<div className="mx-auto max-w-4xl text-center">
{/* Headline */}
<h2
className={`mb-4 text-3xl font-bold tracking-tight sm:text-4xl md:text-5xl ${styles.headline}`}
>
{headline}
</h2>
{/* Description */}
{description && (
<p className={`mb-8 text-lg sm:text-xl ${styles.description}`}>
{description}
</p>
)}
{/* CTAs */}
<div className="flex flex-col items-center justify-center gap-4 sm:flex-row">
<Button
size="lg"
onClick={primaryCTA.onClick}
className={`group w-full font-medium sm:w-auto ${styles.primaryButton}`}
>
{primaryCTA.text}
<ArrowRight className="ml-2 h-4 w-4 transition-transform group-hover:translate-x-1" />
</Button>
{secondaryCTA && (
<Button
size="lg"
variant="outline"
onClick={secondaryCTA.onClick}
className={`w-full font-medium sm:w-auto ${styles.secondaryButton}`}
>
{secondaryCTA.text}
</Button>
)}
</div>
</div>
</div>
</section>
);
}Update the import paths to match your project setup.
import { Button } from "@/components/ui/button";Features
- ✅ Full-width banner - Spans entire viewport width
- ✅ Theme variants - Default, Primary, and Dark themes
- ✅ Dual CTAs - Primary and optional secondary button
- ✅ Responsive - Stacks on mobile, inline on desktop
- ✅ Customizable - All text and actions configurable
- ✅ Accessible - Keyboard navigation and semantic HTML
- ✅ TypeScript support - Full type safety
- ✅ Production-ready - Copy and paste to use
Usage
Basic Usage
import CTABannerSimple from "@/components/ui/cta-banner-simple";
export default function Page() {
return (
<CTABannerSimple
headline="Ready to get started?"
description="Join thousands of teams already using our platform."
primaryCTA={{
text: "Start Free Trial",
onClick: () => console.log("CTA clicked"),
}}
/>
);
}Theme Variants
{/* Default - Subtle muted background */}
<CTABannerSimple
variant="default"
headline="Ready to get started?"
primaryCTA={{ text: "Get Started", onClick: () => {} }}
/>
{/* Primary - Full brand color background */}
<CTABannerSimple
variant="primary"
headline="Ready to get started?"
primaryCTA={{ text: "Get Started", onClick: () => {} }}
/>
{/* Dark - Deep dark theme with white text */}
<CTABannerSimple
variant="dark"
headline="Ready to get started?"
primaryCTA={{ text: "Get Started", onClick: () => {} }}
/>With Secondary CTA
<CTABannerSimple
headline="Ready to get started?"
description="Join thousands of teams already using our platform."
primaryCTA={{
text: "Start Free Trial",
onClick: () => {},
}}
secondaryCTA={{
text: "Contact Sales",
onClick: () => {},
}}
/>With Router Navigation
"use client";
import { useRouter } from "next/navigation";
import CTABannerSimple from "@/components/ui/cta-banner-simple";
export default function Page() {
const router = useRouter();
return (
<CTABannerSimple
headline="Ready to transform your workflow?"
description="Start your 14-day free trial today. No credit card required."
primaryCTA={{
text: "Get Started",
onClick: () => router.push("/signup"),
}}
secondaryCTA={{
text: "Learn More",
onClick: () => router.push("/features"),
}}
/>
);
}Minimal Version
<CTABannerSimple
headline="Start building today"
primaryCTA={{
text: "Get Started",
onClick: () => {},
}}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
headline | string | Required | Main CTA headline |
description | string | undefined | Optional description text |
variant | "default" | "primary" | "dark" | "default" | Theme variant |
primaryCTA | object | Required | Primary button configuration |
primaryCTA.text | string | Required | Button text |
primaryCTA.href | string | undefined | Optional link URL |
primaryCTA.onClick | () => void | undefined | Optional click handler |
secondaryCTA | object | undefined | Optional secondary button |
secondaryCTA.text | string | Required | Button text |
secondaryCTA.href | string | undefined | Optional link URL |
secondaryCTA.onClick | () => void | undefined | Optional click handler |
TypeScript Interface
interface CTABannerSimpleProps {
headline: string;
description?: string;
variant?: "default" | "primary" | "dark";
primaryCTA: {
text: string;
href?: string;
onClick?: () => void;
};
secondaryCTA?: {
text: string;
href?: string;
onClick?: () => void;
};
}Change Button Styles
<Button
size="lg"
className="bg-gradient-to-r from-primary to-primary/80"
>
{primaryCTA.text}
</Button>Add Icons
import { Rocket, MessageCircle } from "lucide-react";
<Button>
<Rocket className="mr-2 h-4 w-4" />
{primaryCTA.text}
</Button>Center Align Buttons
<div className="flex items-center justify-center gap-4">
{/* buttons */}
</div>Use Cases
Perfect for:
- Bottom of landing pages
- End of blog posts
- Between content sections
- Product pages
- Documentation pages
- Pricing pages
- Feature pages
- About pages
Best Practices
- Keep it simple - One clear message and action
- Action-oriented - Use verbs in button text
- Create urgency - "Start today", "Get started now"
- Remove friction - "No credit card required"
- Contrast - Make buttons stand out
- Mobile-first - Test on small screens
- A/B test - Try different copy and layouts