Configuration File: config/promotions/sale-banner.ts
Overview
The sale banner appears at the top of your website with a countdown timer for limited-time promotions:
Countdown timer showing days, hours, minutes, seconds
Customizable offer details and savings
Call-to-action button
Shows “Sale Ended” message when expired
The banner does
not auto-hide when the sale ends. It displays “Sale Ended • Thanks for your interest!” To completely remove it, see
Removing the Banner below.
Configuration file: config/promotions/sale-banner.ts
Quick Start
Set sale end date
Open config/promotions/sale-banner.ts: export const saleBannerConfig = {
saleEndDate: "2026-02-15 23:59:59" , // UTC timezone
// ...
};
Customize offer details
Update discount, duration, and savings text
Test it
Banner appears at the top of every page until the sale ends
Configuration Structure
export const saleBannerConfig = {
// Sale end date (UTC timezone)
// Format: "YYYY-MM-DD HH:mm:ss"
// Set a past date to hide the banner
saleEndDate: "2026-02-15 23:59:59" ,
offer: {
badge: "Limited Offer" , // Small badge text
discount: "40% OFF" , // Main discount text
duration: "First Month" , // What the discount applies to
savings: "Save up to $47.99" , // How much they save
},
// Text shown below the offer
subtext: "Auto-applied at checkout • No credit card required to try" ,
cta: {
text: "Claim Offer" ,
link: "#pricing" , // Where to go when clicked
},
timerLabels: {
prefix: "Ends in:" ,
days: "days" ,
hours: "hrs" ,
minutes: "min" ,
seconds: "sec" ,
},
styling: {
showPulsingDot: true , // Animated dot next to badge
showTimerDividers: true , // Colons between time numbers
}
};
Fields Explained
Sale End Date
saleEndDate : "2026-02-15 23:59:59"
Important :
Uses UTC timezone (not your local time)
Format: "YYYY-MM-DD HH:mm:ss"
Set a past date to hide the banner
Banner auto-hides when time expires
To hide banner : Set to yesterday’s date:
saleEndDate : "2024-01-01 00:00:00"
Offer Details
offer : {
badge : "Limited Offer" , // Top-left badge
discount : "40% OFF" , // Big bold text
duration : "First Month" , // When discount applies
savings : "Save up to $47.99" , // Amount saved
}
Examples :
// Percentage off
{ badge : "Flash Sale" , discount : "50% OFF" , duration : "All Plans" , savings : "Save up to $99" }
// Fixed amount off
{ badge : "Special Deal" , discount : "$20 OFF" , duration : "First Month" , savings : "Limited time" }
// Free trial
{ badge : "Try Free" , discount : "7 Days Free" , duration : "No Credit Card" , savings : "Cancel anytime" }
Subtext
subtext : "Auto-applied at checkout • No credit card required to try"
Additional details or disclaimers. Common examples:
"Auto-applied at checkout • No code needed"
"For new customers only • Limited slots available"
"While supplies last • Terms apply"
Call to Action
cta : {
text : "Claim Offer" ,
link : "#pricing" , // "#section" or "/page"
}
Link options :
Same page section: "#pricing", "#plans"
Another page: "/games", "/vps"
External URL: "https://checkout.yoursite.com"
Timer Labels
timerLabels : {
prefix : "Ends in:" ,
days : "days" ,
hours : "hrs" ,
minutes : "min" ,
seconds : "sec" ,
}
Customize countdown timer text. Days only appear when sale is more than 24 hours away. Examples:
// Short form
{ prefix : "Ends:" , days : "d" , hours : "h" , minutes : "m" , seconds : "s" }
// Long form
{ prefix : "Sale ends in:" , days : "days" , hours : "hours" , minutes : "minutes" , seconds : "seconds" }
// Urgent
{ prefix : "Hurry! Only" , days : "days" , hours : "hours" , minutes : "mins" , seconds : "secs" }
Styling Options
styling : {
showPulsingDot : true , // Animated dot next to badge
showTimerDividers : true , // Colons between time numbers
}
showPulsingDot: Adds attention-grabbing animation
showTimerDividers: Shows : between hours:minutes:seconds
Complete Examples
Black Friday Sale
export const saleBannerConfig = {
saleEndDate: "2026-11-30 23:59:59" ,
offer: {
badge: "Black Friday" ,
discount: "60% OFF" ,
duration: "All Plans" ,
savings: "Save up to $120" ,
},
subtext: "Biggest sale of the year • Limited time only" ,
cta: {
text: "Shop Now" ,
link: "/games" ,
},
timerLabels: {
prefix: "Sale ends in:" ,
hours: "hours" ,
minutes: "min" ,
seconds: "sec" ,
},
styling: {
showPulsingDot: true ,
showTimerDividers: true ,
}
};
New Customer Offer
export const saleBannerConfig = {
saleEndDate: "2026-03-31 23:59:59" ,
offer: {
badge: "New Customer" ,
discount: "30% OFF" ,
duration: "First 3 Months" ,
savings: "Save up to $90" ,
},
subtext: "Auto-applied at checkout • For new accounts only" ,
cta: {
text: "Get Started" ,
link: "#pricing" ,
},
timerLabels: {
prefix: "Ends:" ,
hours: "h" ,
minutes: "m" ,
seconds: "s" ,
},
styling: {
showPulsingDot: true ,
showTimerDividers: false ,
}
};
export const saleBannerConfig = {
saleEndDate: "2026-12-31 23:59:59" ,
offer: {
badge: "Limited Offer" ,
discount: "7 Days Free" ,
duration: "Try Risk-Free" ,
savings: "No credit card required" ,
},
subtext: "Cancel anytime • No commitments" ,
cta: {
text: "Start Free Trial" ,
link: "/games" ,
},
timerLabels: {
prefix: "Offer ends:" ,
hours: "hrs" ,
minutes: "min" ,
seconds: "sec" ,
},
styling: {
showPulsingDot: true ,
showTimerDividers: true ,
}
};
Removing the Banner
The sale banner does not auto-hide when it expires. It will display “Sale Ended • Thanks for your interest!” until you remove it from the code.
To completely remove the sale banner from your site:
Open app/page.tsx
Find the homepage file at app/page.tsx
Remove the SaleBanner component
Delete the import and the component: // BEFORE
import SaleBanner from "@/components/sections/shared/SaleBanner" ;
export default function Home () {
return (
< main className = "min-h-screen" >
< Hero />
< SaleBanner /> { /* Remove this line */ }
< Pricing />
...
</ main >
);
}
// AFTER
export default function Home () {
return (
< main className = "min-h-screen" >
< Hero />
< Pricing />
...
</ main >
);
}
Save and test
The banner is now completely removed from your site.
You can move <SaleBanner /> to other pages like /games or /vps if you want it to appear only on specific pages.
Best Practices
Timing
Set realistic deadlines - Don’t fake urgency
Use UTC timezone - Consistent for all users
Plan ahead - Schedule sales in advance
Update regularly - Remove expired banners promptly
Offer Copy
Be specific - “40% OFF” is better than “HUGE DISCOUNT”
Show value - Include “Save up to $X”
Clear duration - “First Month”, “3 Months”, “Annually”
One clear message - Don’t overcomplicate
Call to Action
Action verbs - “Claim”, “Get”, “Start”, “Shop”
Urgency - “Claim Now”, “Get Offer”
Clear destination - Link to pricing or games
Short text - 2-3 words max
Visibility
Don’t overuse - Constant sales reduce impact
Remove when expired - Set past date to hide
Test on mobile - Ensure text is readable
Monitor conversions - Track banner click-through rate
Troubleshooting
Banner not showing
Check:
Sale end date is in the future
Date format is correct: "YYYY-MM-DD HH:mm:ss"
Time is in UTC , not local timezone
No syntax errors in config file
Timer shows wrong time
The timer uses UTC. To convert your local time to UTC:
EST/EDT: Add 5 hours (or 4 during DST)
PST/PDT: Add 8 hours (or 7 during DST)
GMT: Same as UTC
Use: https://www.worldtimebuddy.com/ for conversion
Banner shows “Sale Ended” message
This is expected behavior! When the sale expires, the banner displays “Sale Ended • Thanks for your interest!” instead of hiding.
To completely remove the banner , see Removing the Banner above.
To just show the “Sale Ended” message , set a past date:
saleEndDate : "2024-01-01 00:00:00"
Text too long on mobile
Keep text concise:
Badge: 2-3 words
Discount: 2-4 words
Duration: 2-3 words
CTA: 2-3 words
Toggle dividers:
styling : {
showTimerDividers : false // Removes colons
}