Experience the Future
Transform your business with cutting-edge technology and innovative solutions
Why Choose Us
Trusted by industry leaders worldwide
Features
- ✅ Full-screen video - Immersive background experience
- ✅ Autoplay - Starts automatically on load
- ✅ Video controls - Play/pause and mute/unmute buttons
- ✅ Customizable overlay - Adjustable darkness level
- ✅ Dual CTAs - Primary and secondary action buttons
- ✅ Scroll indicator - Animated bounce effect
- ✅ Responsive - Works on all screen sizes
- ✅ Mobile optimized - Uses playsInline for iOS
- ✅ Hover effects - Scale animations on buttons
- ✅ TypeScript support - Full type safety
Installation
Copy and paste the following code into your project.
"use client";
import { useState, useRef, useEffect } from "react";
import { Play, Pause, Volume2, VolumeX } from "lucide-react";
interface HeroVideoBackgroundProps {
videoUrl?: string;
title: string;
description: string;
primaryCTA?: {
text: string;
href: string;
};
secondaryCTA?: {
text: string;
href: string;
};
showControls?: boolean;
overlayOpacity?: number;
className?: string;
}
export function HeroVideoBackground({
videoUrl = "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
title,
description,
primaryCTA,
secondaryCTA,
showControls = true,
overlayOpacity = 0.6,
className = "",
}: HeroVideoBackgroundProps) {
const [isPlaying, setIsPlaying] = useState(true);
const [isMuted, setIsMuted] = useState(true);
const videoRef = useRef<HTMLVideoElement>(null);
useEffect(() => {
if (videoRef.current) {
videoRef.current.play().catch(() => {
setIsPlaying(false);
});
}
}, []);
const togglePlay = () => {
if (videoRef.current) {
if (isPlaying) {
videoRef.current.pause();
} else {
videoRef.current.play();
}
setIsPlaying(!isPlaying);
}
};
const toggleMute = () => {
if (videoRef.current) {
videoRef.current.muted = !isMuted;
setIsMuted(!isMuted);
}
};
return (
<section
className={`relative flex min-h-screen items-center justify-center rounded overflow-hidden ${className}`}
>
<video
ref={videoRef}
autoPlay
loop
muted
playsInline
className="absolute inset-0 h-full w-full object-cover"
>
<source src={videoUrl} type="video/mp4" />
</video>
<div
className="absolute inset-0 bg-black"
style={{ opacity: overlayOpacity }}
/>
<div className="relative z-10 mx-auto max-w-5xl px-4 text-center sm:px-6 lg:px-8">
<h1 className="mb-6 text-5xl font-bold leading-tight text-white sm:text-6xl lg:text-7xl">
{title}
</h1>
<p className="mb-10 text-xl text-zinc-300 sm:text-2xl lg:text-3xl">
{description}
</p>
{(primaryCTA || secondaryCTA) && (
<div className="flex flex-col items-center justify-center gap-4 sm:flex-row">
{primaryCTA && (
<a
href={primaryCTA.href}
className="inline-flex items-center gap-2 rounded-lg bg-orange-600 px-8 py-4 text-lg font-semibold text-white transition-all hover:bg-orange-700 hover:scale-105"
>
{primaryCTA.text}
</a>
)}
{secondaryCTA && (
<a
href={secondaryCTA.href}
className="inline-flex items-center gap-2 rounded-lg border-2 border-white bg-white/10 px-8 py-4 text-lg font-semibold text-white backdrop-blur-sm transition-all hover:bg-white/20 hover:scale-105"
>
{secondaryCTA.text}
</a>
)}
</div>
)}
</div>
{showControls && (
<div className="absolute bottom-8 right-8 z-20 flex gap-2">
<button
onClick={togglePlay}
className="rounded-lg bg-black/50 p-3 text-white backdrop-blur-sm transition-all hover:bg-black/70"
aria-label={isPlaying ? "Pause video" : "Play video"}
>
{isPlaying ? (
<Pause className="h-5 w-5" />
) : (
<Play className="h-5 w-5" />
)}
</button>
<button
onClick={toggleMute}
className="rounded-lg bg-black/50 p-3 text-white backdrop-blur-sm transition-all hover:bg-black/70"
aria-label={isMuted ? "Unmute video" : "Mute video"}
>
{isMuted ? (
<VolumeX className="h-5 w-5" />
) : (
<Volume2 className="h-5 w-5" />
)}
</button>
</div>
)}
<div className="absolute bottom-8 left-1/2 z-10 -translate-x-1/2 animate-bounce">
<div className="flex h-12 w-8 items-start justify-center rounded-full border-2 border-white/50 p-2">
<div className="h-2 w-1 animate-pulse rounded-full bg-white" />
</div>
</div>
</section>
);
}Usage
Basic Usage
import HeroVideoBackground from "@/components/ui/hero-video-background";
export default function Page() {
return (
<HeroVideoBackground
title="Experience the Future"
description="Transform your business with cutting-edge technology"
primaryCTA={{
text: "Get Started",
href: "/signup",
}}
secondaryCTA={{
text: "Watch Demo",
href: "/demo",
}}
/>
);
}Custom Video URL
<HeroVideoBackground
videoUrl="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
title="Your Title"
description="Your description"
primaryCTA={{
text: "Get Started",
href: "#",
}}
/>Adjust Overlay Opacity
<HeroVideoBackground
title="Lighter Overlay"
description="More visible video background"
overlayOpacity={0.4} // 0 = transparent, 1 = fully dark
primaryCTA={{
text: "Get Started",
href: "#",
}}
/>Without Video Controls
<HeroVideoBackground
title="Clean Look"
description="No video controls visible"
showControls={false}
primaryCTA={{
text: "Get Started",
href: "#",
}}
/>Single CTA
<HeroVideoBackground
title="Simple Hero"
description="Just one call to action"
primaryCTA={{
text: "Get Started",
href: "#",
}}
// No secondaryCTA
/>Props
HeroVideoBackgroundProps
| Prop | Type | Default | Description |
|---|---|---|---|
videoUrl | string | Google sample video | Video source URL |
title | string | Required | Main heading text |
description | string | Required | Subheading text |
primaryCTA | { text: string; href: string } | undefined | Primary button |
secondaryCTA | { text: string; href: string } | undefined | Secondary button |
showControls | boolean | true | Show video controls |
overlayOpacity | number | 0.6 | Overlay darkness (0-1) |
className | string | "" | Additional CSS classes |
TypeScript Interface
interface HeroVideoBackgroundProps {
videoUrl?: string;
title: string;
description: string;
primaryCTA?: {
text: string;
href: string;
};
secondaryCTA?: {
text: string;
href: string;
};
showControls?: boolean;
overlayOpacity?: number;
className?: string;
}Video Sources
Working Test Videos
For testing and demos, use these reliable sources:
- Google Cloud Storage -
https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/- BigBuckBunny.mp4
- ElephantsDream.mp4
- ForBiggerBlazes.mp4
- Sintel.mp4
Free Video Resources (Download & Self-Host)
For production, download videos and host them yourself:
- Pexels - https://www.pexels.com/videos/ (Free, no attribution)
- Pixabay - https://pixabay.com/videos/ (Free, no attribution)
- Coverr - https://coverr.co/ (Free for commercial use)
- Videvo - https://www.videvo.net/ (Free & premium)
Important: Many free video sites block hotlinking. Always download and host videos on your own server or CDN.
Use Cases
Perfect for:
- Landing pages
- Product launches
- Brand showcases
- Event promotions
- Portfolio sites
- Agency websites
- SaaS homepages
- Marketing campaigns
Customization
Add Gradient Overlay
<div className="absolute inset-0 bg-gradient-to-b from-black/50 via-black/60 to-black/80" />Add Animated Text
<h1 className="mb-6 animate-fade-in text-5xl font-bold">
{title}
</h1>Add Stats or Features
<div className="mt-12 grid grid-cols-3 gap-8">
<div>
<div className="text-4xl font-bold text-white">10K+</div>
<div className="text-zinc-400">Users</div>
</div>
{/* More stats */}
</div>Custom Scroll Indicator
<div className="absolute bottom-8 left-1/2 -translate-x-1/2">
<ChevronDown className="h-8 w-8 animate-bounce text-white" />
</div>