Docs
Demo Request CTA

Demo Request CTA

A stunning call-to-action section for scheduling product demos. Features a beautiful gradient background and multi-field form.

Schedule a Demo

See it in action

Get a personalized walkthrough of our platform and discover how we can help your team succeed.

  • 30-minute personalized demo
  • See real-world use cases
  • Get answers to your questions
  • No commitment required

Get Your Free Demo

No credit card required. Free 30-minute session.

Installation

Copy and paste the following code into your project.

"use client";
 
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Calendar, Check, Loader2, Mail, User } from "lucide-react";
import { useState } from "react";
 
interface DemoRequestProps {
  headline: string;
  description?: string;
  benefits?: string[];
  onSubmit?: (data: DemoFormData) => Promise<void> | void;
}
 
interface DemoFormData {
  name: string;
  email: string;
  company: string;
}
 
export function CTADemoRequest({
  headline,
  description,
  benefits,
  onSubmit,
}: DemoRequestProps) {
  const [formData, setFormData] = useState<DemoFormData>({
    name: "",
    email: "",
    company: "",
  });
  const [isLoading, setIsLoading] = useState(false);
  const [isSuccess, setIsSuccess] = useState(false);
 
  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (onSubmit) {
      setIsLoading(true);
      try {
        await onSubmit(formData);
        setIsSuccess(true);
        setFormData({ name: "", email: "", company: "" });
      } catch (error) {
        console.error("Demo request error:", error);
      } finally {
        setIsLoading(false);
      }
    }
  };
 
  const handleChange = (field: keyof DemoFormData, value: string) => {
    setFormData((prev) => ({ ...prev, [field]: value }));
  };
 
  return (
    <section className="relative overflow-hidden bg-violet-600 py-20 sm:py-24 rounded">
      {/* Background decoration */}
      <div className="absolute inset-0 bg-[linear-gradient(to_right,#ffffff08_1px,transparent_1px),linear-gradient(to_bottom,#ffffff08_1px,transparent_1px)] bg-[size:24px_24px]" />
      <div className="absolute right-0 top-0 h-[500px] w-[500px] rounded-full bg-violet-500/20 blur-3xl" />
      <div className="absolute bottom-0 left-0 h-[500px] w-[500px] rounded-full bg-violet-700/20 blur-3xl" />
 
      <div className="container relative mx-auto px-6">
        <div className="mx-auto max-w-6xl">
          <div className="grid gap-12 lg:grid-cols-2 lg:gap-16">
            {/* Left side - Content */}
            <div className="flex flex-col justify-center">
              <div className="mb-6 w-fit inline-flex items-center gap-2 rounded-full bg-white/10 px-4 py-1.5 backdrop-blur-sm">
                <Calendar className="h-4 w-4 text-white" />
                <span className="text-sm font-semibold text-white">
                  Schedule a Demo
                </span>
              </div>
 
              <h2 className="mb-6 text-4xl font-bold tracking-tight text-white sm:text-5xl lg:text-6xl">
                {headline}
              </h2>
 
              {description && (
                <p className="mb-8 text-lg text-violet-100 sm:text-xl">
                  {description}
                </p>
              )}
 
              {benefits && benefits.length > 0 && (
                <ul className="space-y-4">
                  {benefits.map((benefit, index) => (
                    <li key={index} className="flex items-start gap-3">
                      <div className="mt-0.5 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-white/20">
                        <Check className="h-4 w-4 text-white" strokeWidth={3} />
                      </div>
                      <span className="text-base text-violet-50">
                        {benefit}
                      </span>
                    </li>
                  ))}
                </ul>
              )}
            </div>
 
            {/* Right side - Form */}
            <div className="flex items-center">
              {isSuccess ? (
                <div className="w-full rounded-2xl bg-violet-50 p-8 text-center shadow-xl">
                  <div className="mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-green-500">
                    <Check className="h-8 w-8 text-white" strokeWidth={3} />
                  </div>
                  <h3 className="mb-2 text-2xl font-bold text-gray-900">
                    Request Received!
                  </h3>
                  <p className="text-gray-700">
                    We'll reach out within 24 hours to schedule your
                    personalized demo.
                  </p>
                </div>
              ) : (
                <div className="w-full rounded-2xl bg-violet-50 p-8 shadow-xl">
                  <h3 className="mb-6 text-2xl font-bold text-gray-900">
                    Get Your Free Demo
                  </h3>
 
                  <form onSubmit={handleSubmit} className="space-y-5">
                    <div>
                      <label
                        htmlFor="name"
                        className="mb-2 block text-sm font-medium text-gray-900"
                      >
                        Full Name
                      </label>
                      <div className="relative">
                        <User className="absolute left-3 top-1/2 h-5 w-5 -translate-y-1/2 text-gray-500" />
                        <Input
                          id="name"
                          type="text"
                          placeholder="John Doe"
                          value={formData.name}
                          onChange={(e) => handleChange("name", e.target.value)}
                          required
                          disabled={isLoading}
                          className="h-12 rounded-lg border-violet-200 bg-white pl-10 text-base focus:border-violet-500 focus:ring-violet-500"
                        />
                      </div>
                    </div>
 
                    <div>
                      <label
                        htmlFor="email"
                        className="mb-2 block text-sm font-medium text-gray-900"
                      >
                        Work Email
                      </label>
                      <div className="relative">
                        <Mail className="absolute left-3 top-1/2 h-5 w-5 -translate-y-1/2 text-gray-500" />
                        <Input
                          id="email"
                          type="email"
                          placeholder="john@company.com"
                          value={formData.email}
                          onChange={(e) =>
                            handleChange("email", e.target.value)
                          }
                          required
                          disabled={isLoading}
                          className="h-12 rounded-lg border-violet-200 bg-white pl-10 text-base focus:border-violet-500 focus:ring-violet-500"
                        />
                      </div>
                    </div>
 
                    <div>
                      <label
                        htmlFor="company"
                        className="mb-2 block text-sm font-medium text-gray-900"
                      >
                        Company Name
                      </label>
                      <Input
                        id="company"
                        type="text"
                        placeholder="Acme Inc"
                        value={formData.company}
                        onChange={(e) =>
                          handleChange("company", e.target.value)
                        }
                        required
                        disabled={isLoading}
                        className="h-12 rounded-lg border-violet-200 bg-white text-base focus:border-violet-500 focus:ring-violet-500"
                      />
                    </div>
 
                    <Button
                      type="submit"
                      disabled={isLoading}
                      className="h-12 w-full rounded-lg bg-violet-600 text-base font-semibold text-white shadow-lg shadow-violet-600/30 transition-all hover:bg-violet-700 hover:shadow-xl hover:shadow-violet-600/40"
                    >
                      {isLoading ? (
                        <>
                          <Loader2 className="mr-2 h-5 w-5 animate-spin" />
                          Submitting...
                        </>
                      ) : (
                        "Schedule Demo"
                      )}
                    </Button>
 
                    <p className="text-center text-xs text-gray-600">
                      No credit card required. Free 30-minute session.
                    </p>
                  </form>
                </div>
              )}
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

Update the import paths to match your project setup.

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";

Features

  • Beautiful gradient - Blue to indigo background
  • Multi-field form - Name, email, and company inputs
  • Icon inputs - User and mail icons in fields
  • Success state - Animated confirmation message
  • Loading states - Visual feedback during submission
  • Benefits list - Checkmarks for key selling points
  • Badge indicator - "Schedule a Demo" badge
  • Responsive layout - Side-by-side on desktop, stacked on mobile
  • Form validation - Built-in required field validation
  • TypeScript support - Full type safety

Usage

Basic Usage

import CTADemoRequest from "@/components/ui/cta-demo-request";
 
export default function Page() {
    return (
        <CTADemoRequest
            headline="See it in action"
            description="Get a personalized demo of our platform."
            onSubmit={(data) => console.log("Demo request:", data)}
        />
    );
}

With Benefits List

<CTADemoRequest
    headline="See it in action"
    description="Get a personalized walkthrough of our platform."
    benefits={[
        "30-minute personalized demo",
        "See real-world use cases",
        "Get answers to your questions",
        "No commitment required",
    ]}
    onSubmit={(data) => console.log(data)}
/>

With API Integration

"use client";
 
import CTADemoRequest from "@/components/ui/cta-demo-request";
 
export default function Page() {
    const handleSubmit = async (data: {
        name: string;
        email: string;
        company: string;
    }) => {
        try {
            const response = await fetch("/api/demo-request", {
                method: "POST",
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify(data),
            });
 
            if (response.ok) {
                // Success handled by component
            }
        } catch (error) {
            console.error("Demo request failed:", error);
        }
    };
 
    return (
        <CTADemoRequest
            headline="See it in action"
            description="Get a personalized demo."
            benefits={[
                "30-minute personalized demo",
                "See real-world use cases",
                "Get answers to your questions",
            ]}
            onSubmit={handleSubmit}
        />
    );
}

Minimal Version

<CTADemoRequest
    headline="Request a Demo"
    onSubmit={(data) => console.log(data)}
/>

Props

PropTypeDefaultDescription
headlinestringRequiredMain headline text
descriptionstringundefinedSupporting description
benefitsstring[]undefinedList of benefits with checkmarks
onSubmit(data: DemoFormData) => voidundefinedForm submission handler

TypeScript Interface

interface DemoRequestProps {
    headline: string;
    description?: string;
    benefits?: string[];
    onSubmit?: (data: DemoFormData) => Promise<void> | void;
}
 
interface DemoFormData {
    name: string;
    email: string;
    company: string;
}

Use Cases

Perfect for:

  • SaaS product demos
  • B2B lead generation
  • Sales team scheduling
  • Product walkthroughs
  • Consultation requests
  • Trial signups
  • Enterprise sales
  • Platform previews