Code component
Code component
Code component
Code component
Countdown Widget
Countdown Widget
Countdown Widget
Countdown Widget
Use this widget (code component) on your Framer website to add a customizable countdown element to it. This can be used for product launches, limited time offers, and more.
Use this widget (code component) on your Framer website to add a customizable countdown element to it. This can be used for product launches, limited time offers, and more.
Use this widget (code component) on your Framer website to add a customizable countdown element to it. This can be used for product launches, limited time offers, and more.
Use this widget (code component) on your Framer website to add a customizable countdown element to it. This can be used for product launches, limited time offers, and more.




Features
Fully customizable through component properties.
You can:
Change font size.
Change text color.
Specify font family & weight.
Toggle days, hours, minutes, and seconds.
Specify an end date.
Specify an end message.

Step / 01
Copy the component.

Step / 02
Paste it into your project.

Step / 03
Customize it with the component properties.
Source code
If you want to take a look at how such a code component is built in Framer, feel free to copy this code from below and dig into it.
// © Framer University. All rights reserved.
import React, { useState, useEffect } from "react"
import { addPropertyControls, ControlType } from "framer"
export default function Countdown({
fontSize,
fontFamily,
fontColor,
fontWeight,
displayDays,
displayHours,
displayMinutes,
displaySeconds,
endDate,
endTime,
endMessage,
}) {
const [timeLeft, setTimeLeft] = useState(calculateTimeLeft())
useEffect(() => {
const timer = setTimeout(() => {
setTimeLeft(calculateTimeLeft())
}, 1000)
return () => clearTimeout(timer)
})
function calculateTimeLeft() {
const difference = +new Date(`${endDate}T${endTime}`) - +new Date()
let timeLeft = {}
if (difference > 0) {
if (difference < 60 * 60 * 1000) {
// Less than 60 minutes remaining
const minutes = Math.floor((difference / (1000 * 60)) % 60)
const seconds = Math.floor((difference / 1000) % 60)
timeLeft = {
days: displayDays ? 0 : null,
hours: displayHours ? 0 : null,
minutes: displayMinutes ? minutes : null,
seconds: displaySeconds ? seconds : null,
}
} else {
const time = {
d: Math.floor(difference / (1000 * 60 * 60 * 24)),
h: Math.floor((difference / (1000 * 60 * 60)) % 24),
m: Math.floor((difference / (1000 * 60)) % 60),
s: Math.floor((difference / 1000) % 60),
}
timeLeft = {
days: displayDays ? time.d : 0,
hours: displayHours ? time.h : null,
minutes: displayMinutes ? time.m : null,
seconds: displaySeconds ? time.s : null,
}
}
}
return timeLeft
}
const timerComponents = []
Object.keys(timeLeft).forEach((interval) => {
if (!timeLeft[interval]) {
return
}
timerComponents.push(
<span
key={interval}
style={{
display: "flex",
alignItems: "center",
flexDirection: "column",
}}
>
{timeLeft[interval]}
<span style={{ fontSize: `${fontSize / 2.5}px` }}>
{interval.toLowerCase()}
</span>
</span>
)
})
return (
<div
style={{
fontSize,
fontFamily,
color: fontColor,
fontWeight,
display: "flex",
gap: "20px",
}}
>
{timerComponents.length ? (
timerComponents
) : (
<span>{endMessage}</span>
)}
</div>
)
}
addPropertyControls(Countdown, {
fontSize: {
type: ControlType.Number,
unit: "px",
defaultValue: 30,
},
fontFamily: {
type: ControlType.String,
defaultValue: "Inter",
},
fontColor: {
type: ControlType.Color,
defaultValue: "black",
},
fontWeight: {
type: ControlType.Enum,
defaultValue: 400,
options: [
"normal",
"bold",
"bolder",
"lighter",
100,
200,
300,
400,
500,
600,
700,
800,
900,
],
},
displayDays: {
type: ControlType.Boolean,
defaultValue: true,
},
displayHours: {
type: ControlType.Boolean,
defaultValue: true,
},
displayMinutes: {
type: ControlType.Boolean,
defaultValue: true,
},
displaySeconds: {
type: ControlType.Boolean,
defaultValue: true,
},
endDate: {
type: ControlType.String,
defaultValue: "2023-04-25",
description: "YYYY-MM-DD",
},
endTime: {
type: ControlType.String,
defaultValue: "00:00:00",
description: "HH:MM:SS",
},
endMessage: {
type: ControlType.String,
defaultValue: "Time's up!",
},
})
// © Framer University. All rights reserved.
import React, { useState, useEffect } from "react"
import { addPropertyControls, ControlType } from "framer"
export default function Countdown({
fontSize,
fontFamily,
fontColor,
fontWeight,
displayDays,
displayHours,
displayMinutes,
displaySeconds,
endDate,
endTime,
endMessage,
}) {
const [timeLeft, setTimeLeft] = useState(calculateTimeLeft())
useEffect(() => {
const timer = setTimeout(() => {
setTimeLeft(calculateTimeLeft())
}, 1000)
return () => clearTimeout(timer)
})
function calculateTimeLeft() {
const difference = +new Date(`${endDate}T${endTime}`) - +new Date()
let timeLeft = {}
if (difference > 0) {
if (difference < 60 * 60 * 1000) {
// Less than 60 minutes remaining
const minutes = Math.floor((difference / (1000 * 60)) % 60)
const seconds = Math.floor((difference / 1000) % 60)
timeLeft = {
days: displayDays ? 0 : null,
hours: displayHours ? 0 : null,
minutes: displayMinutes ? minutes : null,
seconds: displaySeconds ? seconds : null,
}
} else {
const time = {
d: Math.floor(difference / (1000 * 60 * 60 * 24)),
h: Math.floor((difference / (1000 * 60 * 60)) % 24),
m: Math.floor((difference / (1000 * 60)) % 60),
s: Math.floor((difference / 1000) % 60),
}
timeLeft = {
days: displayDays ? time.d : 0,
hours: displayHours ? time.h : null,
minutes: displayMinutes ? time.m : null,
seconds: displaySeconds ? time.s : null,
}
}
}
return timeLeft
}
const timerComponents = []
Object.keys(timeLeft).forEach((interval) => {
if (!timeLeft[interval]) {
return
}
timerComponents.push(
<span
key={interval}
style={{
display: "flex",
alignItems: "center",
flexDirection: "column",
}}
>
{timeLeft[interval]}
<span style={{ fontSize: `${fontSize / 2.5}px` }}>
{interval.toLowerCase()}
</span>
</span>
)
})
return (
<div
style={{
fontSize,
fontFamily,
color: fontColor,
fontWeight,
display: "flex",
gap: "20px",
}}
>
{timerComponents.length ? (
timerComponents
) : (
<span>{endMessage}</span>
)}
</div>
)
}
addPropertyControls(Countdown, {
fontSize: {
type: ControlType.Number,
unit: "px",
defaultValue: 30,
},
fontFamily: {
type: ControlType.String,
defaultValue: "Inter",
},
fontColor: {
type: ControlType.Color,
defaultValue: "black",
},
fontWeight: {
type: ControlType.Enum,
defaultValue: 400,
options: [
"normal",
"bold",
"bolder",
"lighter",
100,
200,
300,
400,
500,
600,
700,
800,
900,
],
},
displayDays: {
type: ControlType.Boolean,
defaultValue: true,
},
displayHours: {
type: ControlType.Boolean,
defaultValue: true,
},
displayMinutes: {
type: ControlType.Boolean,
defaultValue: true,
},
displaySeconds: {
type: ControlType.Boolean,
defaultValue: true,
},
endDate: {
type: ControlType.String,
defaultValue: "2023-04-25",
description: "YYYY-MM-DD",
},
endTime: {
type: ControlType.String,
defaultValue: "00:00:00",
description: "HH:MM:SS",
},
endMessage: {
type: ControlType.String,
defaultValue: "Time's up!",
},
})



Free Framer Course
Learn how to create stunning websites with ease by learning the fundamentals of Framer.



Free
Framer Course
Learn how to create stunning websites with ease by learning the fundamentals of Framer.



Free Framer Course
Learn how to create stunning websites with ease by learning the fundamentals of Framer.