Recent Purchase Notification Popup — Free HTML CSS JS FOMO Toast Snippet

Recent Purchase Notification Popup · Modals · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Chained setTimeout show/hide loop — never overlaps or double-fires like a raw setInterval could
Spring-like cubic-bezier easing gives the slide-in a subtle overshoot-and-settle feel
Cycles indefinitely through an array of notifications, wrapping back to the start automatically
Manual dismissal schedules the next toast slightly later, as a courtesy to the user
role="status" and aria-live="polite" announce each new notification to screen readers
All notification content driven by a single easily editable data array — no repeated markup
Fixed bottom-left positioning keeps it out of the way of typical bottom-right chat widgets
Avatar initials generated directly from the data, no image assets required
Close button always available so users can dismiss an individual toast early
No framework, no third-party social-proof service or script, no build step required

About this UI Snippet

Recent Purchase Notification Popup — HTML, CSS & JavaScript FOMO Toast

Screenshot of the Recent Purchase Notification Popup snippet rendered live

A "recent purchase" or "FOMO" notification is the small toast — popularized by tools like Fomo and Proof — that periodically appears in the corner of an e-commerce site showing something like "Jordan D. in New York just bought Wireless Headphones." It's a lightweight social-proof signal that other real people are actively buying, meant to nudge hesitant visitors.

This snippet implements the full cycling behavior in plain HTML, CSS, and vanilla JavaScript, with no third-party social-proof service.

How the notification queue works

A plain array, NOTIFICATIONS, holds a handful of { initials, name, location, product, time } objects. An index variable tracks which one is currently showing, and renderNotification fills the toast's avatar initials, message text, and timestamp from whichever entry is at that index. (index + 1) % NOTIFICATIONS.length advances to the next entry and wraps back to the start once the list is exhausted — so the cycle repeats indefinitely.

How the slide-in/out animation works

The toast sits fixed at bottom: 24px; left: 24px with transform: translateX(-120%) by default — fully off-screen to the left. Adding the .visible class animates it to translateX(0) using a spring-like cubic-bezier(0.22, 1, 0.36, 1) easing curve, which gives a slight overshoot-and-settle feel rather than a plain linear slide.

How the show → wait → hide → cycle loop works

Two named timing constants drive the whole loop: VISIBLE_DURATION (how long each toast stays on screen before auto-hiding) and GAP_BETWEEN (how long the toast stays completely off-screen before the next one appears). showToast() displays the current notification and schedules hideToast() after VISIBLE_DURATION. hideToast() removes the .visible class, advances the index, and schedules the next showToast() after GAP_BETWEEN. Because each function schedules the other via setTimeout, the cycle runs indefinitely without a setInterval, which is important — a fixed interval would fire even while a previous toast's exit animation was still playing, whereas this chained-timeout approach always waits for the current toast's full cycle to finish first.

Manual dismissal

Clicking the × button calls hideToast(true), which behaves identically to the automatic timeout except it schedules the *next* notification slightly further out (GAP_BETWEEN * 1.5) — a small courtesy so a visitor who explicitly closed a toast isn't immediately shown another one.

Accessibility

The toast has role="status" and aria-live="polite", so screen readers announce each new notification's text as it appears, without interrupting whatever the user is currently doing.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Give this snippet's HTML, CSS, and JS to an AI coding assistant like Claude and ask it to explain why alternating setTimeout calls between the show and hide functions avoids the overlap and timing-drift problems a single repeating setInterval would introduce for this kind of cyclic toast animation. It's also worth discussing the ethics and legal considerations of this pattern with the assistant — ask it to help you design a version that only ever displays genuine, real-time purchase events pulled from your actual order system, since presenting fabricated activity as real social proof can be misleading to users and is restricted under consumer protection regulations in several jurisdictions.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a "recent purchase" social-proof toast notification that periodically cycles through a list of items in plain HTML, CSS, and JavaScript — no third-party social-proof service or script.

Requirements:
- A toast fixed near a bottom corner of the viewport, hidden off-screen by default via a CSS transform, that slides into view with a spring-like eased transition when shown.
- A data-driven notification queue (a plain array of objects with fields like name, location, product, and a relative timestamp) that the toast renders from, with a single render function that updates the toast's content from whichever entry is currently active.
- Implement the show/wait/hide/cycle loop using chained setTimeout calls between a show function and a hide function — not a single repeating setInterval — so that each phase only begins once the previous one has actually completed, and the cycle wraps back to the first entry after the last one.
- Include a close button that lets the user dismiss the current toast immediately, which should also cause the next notification in the cycle to wait somewhat longer than usual before appearing, as a courtesy.
- Give the toast container role="status" and aria-live="polite" so each new notification is announced to screen reader users without interrupting their current task or stealing keyboard focus.
- Keep all timing values (how long a toast stays visible, how long the gap between toasts is) as clearly named constants near the top of the script so they are easy to tune.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Load the snippetClick "Recent Purchase Notification Popup" in the sidebar Library tab. After about 1.5 seconds, the first toast slides in from the bottom-left.
  2. 2
    Watch it cycleLet it run — the toast auto-dismisses after a few seconds, pauses briefly, then shows the next entry from the notification list, looping indefinitely.
  3. 3
    Dismiss one manuallyClick the × to close a toast early and notice the next one waits slightly longer before appearing.
  4. 4
    Edit the notification listIn the JS panel, edit the NOTIFICATIONS array to reflect real (or realistic) purchases relevant to your store.
  5. 5
    Tune the timingAdjust VISIBLE_DURATION and GAP_BETWEEN in the JS panel to control how long each toast stays visible and how long the gap is between them.
  6. 6
    Connect to real order dataReplace the static NOTIFICATIONS array with data fetched from your order/checkout backend for genuine (not fabricated) recent activity.

Real-world uses

Common Use Cases

STORE
E-commerce social proof
Show visitors that real purchases are happening on your store, without paying for a third-party FOMO/social-proof SaaS product.
Learn chained-timeout animation loops
Study why alternating setTimeout calls between a show and hide function is safer than a single repeating setInterval for cyclic UI.
Prototype conversion-focused landing pages
Drop this into a product launch or landing page prototype to test whether social proof notifications measurably affect signup or purchase rates.
Match your storefront's visual style
Recolor the avatar, adjust the toast shadow and corner radius, and reposition it to fit alongside other UI already on your page.
Announce updates without interrupting users
The aria-live="polite" region ensures screen reader users are informed of new notifications without their current task being forcibly interrupted.
Connect to real, live order data
Replace the static notification array with data pulled from your actual checkout or order-webhook system for authentic, non-fabricated social proof.

Got questions?

Frequently Asked Questions

Not by default — the demo uses a hardcoded array of example notifications. For a legitimate use, replace the array with data fetched from your real order or checkout system rather than fabricating purchases, which can mislead users and run afoul of consumer protection rules in some jurisdictions.

setInterval fires on a fixed schedule regardless of what else is happening, which could trigger the next show while the current toast's hide animation is still playing. Each function here calls setTimeout to schedule the next step only once its own logic has run, keeping the cycle strictly sequential and glitch-free.

Edit the VISIBLE_DURATION constant in the JS panel — it is the number of milliseconds a toast stays on screen before it automatically hides and the cycle advances to the next notification.

Edit the GAP_BETWEEN constant — it is the number of milliseconds the toast stays fully hidden before the next one slides in. Dismissing a toast manually adds a 50% longer pause as a courtesy before the next one appears.

Yes. Replace the NOTIFICATIONS array with data from a WebSocket connection, Server-Sent Events stream, or periodic API poll against your order system, pushing new entries into the array (or a queue) as real purchases happen.

Yes. The toast container has role="status" and aria-live="polite", so assistive technology announces each new notification's text as it appears, without stealing focus or interrupting the user's current task.

Yes. Change left: 24px to right: 24px on .fomo-toast, and flip the initial transform to translateX(120%) so it slides in from the opposite direction.

No — dismissing a toast early just hides it sooner and slightly delays the next one; the cycle continues indefinitely afterward. If you want dismissal to stop the whole feature for a session, you could set a sessionStorage flag inside the close handler and check it before scheduling future notifications.