CategoriesAllHeroNavigationFooterCall-to-ActionsFeature SectionsTestimonialsPricingContactGalleryStatsFAQServicesNewsletterAuthMiscellaneousButtons
All Components3D Cube InteractionBorder Logo GridCountdownFlip ButtonExpandable FAQsFlow ButtonGlow ButtonGrayscale CarouselInertia Zoom ParallaxLogo Cloud GridMobile Drawer NavigationPixel PreloaderProject GalleryRing ButtonShowcase CarouselSlide PreloaderSliding Stairs PreloaderStormtrooper FAQText Gradient OpacityThreads ButtonTilt HeadlineUltra Preloader
Code
app/page.tsx
1import Countdown from "@/components/countdown";
2
3const Home = () => {
4  return (
5    <div className=" bg-[#F3F3F3] h-screen flex items-center justify-center">
6      <Countdown />
7    </div>
8  );
9}
10
11export default Home;Installation
Initialized a project and installed the necessary dependencies to use this component.
1. Initialize a new Next.js project:
npx create-next-app@latest my-app2. Install Framer Motion
npm install framer-motionAdd Countdown Component
src/components/countdown.tsx
1"use client";
2
3import { AnimatePresence, motion } from "framer-motion";
4import { useEffect, useRef, useState } from "react";
5
6// NOTE: Change this date to whatever date you want to countdown to
7const COUNTDOWN_FROM = "04/21/2026";
8
9const SECOND = 1000;
10const MINUTE = SECOND * 60;
11const HOUR = MINUTE * 60;
12const DAY = HOUR * 24;
13
14const Countdown = () => {
15  const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
16
17  const [remaining, setRemaining] = useState({
18    days: 0,
19    hours: 0,
20    minutes: 0,
21    seconds: 0,
22  });
23
24  useEffect(() => {
25    intervalRef.current = setInterval(handleCountdown, 1000);
26
27    return () => clearInterval(intervalRef.current || undefined);
28  }, []);
29
30  const handleCountdown = () => {
31    const end = new Date(COUNTDOWN_FROM);
32
33    const now = new Date();
34
35    const distance = +end - +now;
36
37    const days = Math.floor(distance / DAY);
38    const hours = Math.floor((distance % DAY) / HOUR);
39    const minutes = Math.floor((distance % HOUR) / MINUTE);
40    const seconds = Math.floor((distance % MINUTE) / SECOND);
41
42    setRemaining({
43      days,
44      hours,
45      minutes,
46      seconds,
47    });
48  };
49
50  return (
51    <div>
52      <div className="py-2 px-4 bg-white/70 text-black shadow-sm backdrop-blur-md border border-[#DADADA] rounded-full">
53        <div className="w-full max-w-5xl -mt-4 mx-auto flex items-center rounded-full gap-0">
54          <CountdownItem unit="days" num={remaining.days} />
55          <p className="mx-2  font-semibold text-lg -mt-2">:</p>
56          <CountdownItem unit="hours" num={remaining.hours} />
57          <p className="mx-2  font-semibold text-lg -mt-2">:</p>
58          <CountdownItem unit="minutes" num={remaining.minutes} />
59          <p className="mx-2  font-semibold text-lg -mt-2">:</p>
60          <CountdownItem unit="seconds" num={remaining.seconds} />
61        </div>
62      </div>
63    </div>
64  );
65};
66
67const CountdownItem = ({ num, unit }: { num: number; unit: string }) => {
68  return (
69    <div className=" flex flex-col items-center">
70      <div className=" aspect-square rounded-full w-16 h-16 flex flex-col gap-1 md:gap-0 items-center justify-center">
71        <div className="w-full text-center relative overflow-hidden">
72          <AnimatePresence mode="popLayout">
73            <motion.span
74              key={num}
75              initial={{ y: "100%" }}
76              animate={{ y: "0%" }}
77              exit={{ y: "-100%" }}
78              transition={{ ease: "backIn", duration: 0.75 }}
79              className="block text-lg md:text-2xl font-semibold"
80            >
81              {num}
82            </motion.span>
83          </AnimatePresence>
84        </div>
85      </div>
86      <p className=" -mt-5 opacity-70">{unit}</p>
87    </div>
88  );
89};
90
91export default Countdown;