webdevpuneet.com

Loyalty Program Tier Progress — Free Multi-Tier Rewards Widget

Loyalty Program Tier Progress · Dashboards · Plain HTML, CSS & JS · Live preview

CategoryDashboards

Copy & paste

Source Code

<section class="ltp-wrap">
  <div class="ltp-card">
    <div class="ltp-head">
      <div>
        <span class="ltp-eyebrow">Current tier</span>
        <h2 id="ltpTierName">Silver</h2>
      </div>
      <div class="ltp-badge" id="ltpBadge">🥈</div>
    </div>

    <div class="ltp-points-row">
      <span id="ltpPointsEarned">2,340</span>
      <span class="ltp-points-label">points this cycle</span>
    </div>

    <div class="ltp-progress-head">
      <span id="ltpNextLabel">1,160 pts to Gold</span>
      <span id="ltpPct">67%</span>
    </div>
    <div class="ltp-track"><div class="ltp-fill" id="ltpFill"></div></div>

    <div class="ltp-demo-controls">
      <label for="ltpSlider">Simulate points earned</label>
      <input type="range" id="ltpSlider" min="0" max="12000" value="2340" step="10">
    </div>

    <div class="ltp-tiers" id="ltpTiers"></div>
  </div>
</section>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Five-tier ladder
Bronze through Diamond, each with a real point range.
Per-tier benefit text
Every tier lists what it actually unlocks.
Scoped progress bar
Measures progress within the current tier, not the whole scale.
Exact points-to-next label
The real numeric gap to the next tier threshold.
Highlighted active tier
The full list always shows where the member stands.
Single tier-lookup function
One tierIndexFor() drives every derived value.
Top-tier handling
Gracefully shows 100% with no "next tier" once maxed.
Zero dependencies
Pure DOM and CSS, no charting library.

About this UI Snippet

Loyalty Program Tier Progress — Beyond a Single Points Bar

Screenshot of the Loyalty Program Tier Progress snippet rendered live

A points balance and a progress bar tell you how close you are to *something*, but not what that something actually unlocks. This widget is built around the full tier ladder: five named tiers, each with a real point range and a distinct benefit, with the current tier highlighted in context so the progress bar means something concrete.

A tier lookup, not a raw percentage

TIERS is an ordered array of { name, min, icon, benefit } objects. tierIndexFor(points) walks the list and returns the highest tier whose min threshold the current points have crossed — the same logic a real loyalty backend would use to assign a member's tier. Everything else in the widget derives from that one lookup.

Progress scoped to the current tier's span, not the whole scale

The progress bar doesn't measure points against some fixed maximum — it measures progress *within the current tier's range*: (points - current.min) / (next.min - current.min). That's why the bar resets to a fresh 0-100% at each tier boundary instead of slowly creeping across a single giant scale, and why the "points to next tier" label always shows the exact, correct gap regardless of which tier you're in.

The full ladder, always visible

Below the progress bar, every tier renders as its own row — icon, name, real benefit text, and its point range — with the current tier's row visually highlighted. This is the core difference from a simple points bar: a member can see not just how far they are from the next tier, but exactly what every tier above and below unlocks, which is what actually motivates progress. Drag the demo slider to watch the highlighted row, progress bar, and "points to next tier" label all update together at every tier boundary. Pair this with a quota usage meter for a broader account-status dashboard.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSRenders at 2,340 points — Silver tier, 67% to Gold.
  2. 2
    Drag the demo sliderPoints update live from 0 to 12,000.
  3. 3
    Cross a tier boundaryThe badge, name, and highlighted row all switch instantly.
  4. 4
    Reach the top tierThe progress bar fills and shows "Top tier reached."
  5. 5
    Read the tier listEvery tier shows its real point range and unlocked benefit.
  6. 6
    Wire up real dataCall render(points) with a member's actual point balance.

Real-world uses

Common Use Cases

E-commerce loyalty programmes
Show tier status beside a quota usage meter, with the exact points needed to reach the next of five named tiers.
Subscription and membership apps
Visualise plan-tier progress, listing what each tier unlocks so members know why the next one is worth reaching.
Airline and hotel status pages
Use a real tier ladder with elite benefits, where the progress bar measures within the current tier and not across the whole scale.
Gamified onboarding unlocks
Motivate usage by showing the next unlock and the exact numeric gap to it, which is more compelling than a bare percentage.
Creator and community platforms
Show contributor tiers and what each earns, with the active tier highlighted in the benefits list.
Related: Readability Score Gauge
See the Readability Score Gauge for a related dashboards pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

A single points bar only shows how far a value is toward one fixed target. This widget is built around a full ordered tier ladder (five tiers, each with a real point range and a distinct benefit) — the current tier is looked up from that ladder, the progress bar is scoped to just the span between the current and next tier, and every tier's benefits are always visible in a list with the active one highlighted, so the member can see the whole path, not just the next checkpoint.

Rather than measuring points against a single overall maximum, the bar measures (points - currentTier.min) / (nextTier.min - currentTier.min). That means the bar resets to a fresh 0% right after crossing into a new tier and reaches 100% exactly at the next tier's threshold, so the visual progress always reflects standing within the current tier rather than an oddly compressed fraction of the entire five-tier range.

tierIndexFor() returns the highest tier whose minimum the points have crossed, so once points reach the top tier's threshold, there is no "next" tier to measure against. The code detects this (next is undefined) and fills the bar to 100% with a "Top tier reached" label instead of trying to divide by a nonexistent next threshold.

Yes — the slider just calls the same render(points) function that does everything: finding the current tier, computing progress within it, and re-rendering the highlighted tier list. Call render(memberPointsFromYourBackend) whenever the member's balance loads or changes, and remove the slider if manual demoing isn't needed.

Keep the raw points value in state, derive the current tier index and the next tier's threshold with the same lookup logic, and bind the progress bar's width, the points-to-next label, and the tier list's "active" class to those derived values — the TIERS array itself is static configuration and doesn't need to live in state.