Skip to main content
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

1

Set sale end date

Open config/promotions/sale-banner.ts:
export const saleBannerConfig = {
  saleEndDate: "2026-02-15 23:59:59",  // UTC timezone
  // ...
};
2

Customize offer details

Update discount, duration, and savings text
3

Test it

npm run dev
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,
  }
};

Free Trial Promotion

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:
1

Open app/page.tsx

Find the homepage file at app/page.tsx
2

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>
  );
}
3

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

  1. Set realistic deadlines - Don’t fake urgency
  2. Use UTC timezone - Consistent for all users
  3. Plan ahead - Schedule sales in advance
  4. Update regularly - Remove expired banners promptly

Offer Copy

  1. Be specific - “40% OFF” is better than “HUGE DISCOUNT”
  2. Show value - Include “Save up to $X”
  3. Clear duration - “First Month”, “3 Months”, “Annually”
  4. One clear message - Don’t overcomplicate

Call to Action

  1. Action verbs - “Claim”, “Get”, “Start”, “Shop”
  2. Urgency - “Claim Now”, “Get Offer”
  3. Clear destination - Link to pricing or games
  4. Short text - 2-3 words max

Visibility

  1. Don’t overuse - Constant sales reduce impact
  2. Remove when expired - Set past date to hide
  3. Test on mobile - Ensure text is readable
  4. Monitor conversions - Track banner click-through rate

Troubleshooting

Check:
  1. Sale end date is in the future
  2. Date format is correct: "YYYY-MM-DD HH:mm:ss"
  3. Time is in UTC, not local timezone
  4. 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 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

Timer format looks wrong

Toggle dividers:
styling: {
  showTimerDividers: false  // Removes colons
}