WP Manifestindependent plugin directory
manifest / social / live-pulse

Live Pulse

A real-time WordPress plugin that shows live viewer counts and emoji reactions on any post — built entirely on the native WordPress Interactivity API, with zero jQuery, no external services, and no build step.

by Hafez Fandy · github.com/hafez121/live-pulse · website

0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/hafez121/live-pulse/archive/refs/heads/main.zip

Readme

Live Pulse

Real-time viewer presence and instant emoji reactions for WordPress — built entirely on the native Interactivity API. No React, no build step, no third-party real-time service.

Live Pulse adds two small, live-feeling features to any post or page:

  • 🟢 "X people are viewing this now" — a real-time viewer counter
  • An instant emoji reaction bar — tap a reaction, see it (and everyone else's) update immediately, no refresh

Why this is different

Most "who's viewing" or "reactions" plugins reach for a full JS framework or a third-party real-time service (Pusher, Firebase, a custom WebSocket server). Live Pulse doesn't use any of that.

It's built on the WordPress Interactivity API, introduced in WordPress 6.5 — a native reactivity runtime that ships with WordPress core itself. Combine that with polling against the standard REST API, and you get live-feeling UI with zero extra infrastructure.

Features

  • Live viewer count, powered by self-expiring transients — no custom database table, no cron job
  • Emoji reaction bar with one-reaction-per-visitor (tap again to remove, tap another to switch)
  • Ships as a Gutenberg block, a [live_pulse] shortcode, or auto-inserted before/after content
  • Fully configurable: post types, emoji set, poll interval, presence timeout, minimum viewers before the counter shows
  • No visitor accounts — anonymous sessions use a random ID stored only in the browser
  • Graceful no-JS fallback — the server-rendered count and totals are visible before JavaScript even loads
  • Translation-ready, and cleans up after itself on uninstall if you opt in

How it works

Presence: each visitor's browser pings the server every few seconds (configurable) to say "I'm still here." The server keeps a short-lived list of active sessions per post in a transient and automatically forgets anyone who stops pinging — no cleanup job required.

Reactions: counts are stored in post meta as a simple emoji → count map. Each anonymous session can hold exactly one active reaction per post, remembered for a day, so switching or removing a reaction never inflates the numbers.

Installation

  1. Download the latest release ZIP (or clone this repo into wp-content/plugins/live-pulse).
  2. Activate Live Pulse from the Plugins screen.
  3. Go to Settings → Live Pulse to choose post types, emoji, and display options.
  4. Place it with the block, the [live_pulse] shortcode, or leave auto-insert on.

Requires WordPress 6.5+ (for the Interactivity API) and PHP 7.4+.

File structure

live-pulse/
├── live-pulse.php                      Plugin bootstrap
├── uninstall.php                       Opt-in data cleanup
├── includes/
│   ├── class-live-pulse-settings.php   Options + admin settings page
│   ├── class-live-pulse-presence.php   Transient-based viewer tracking
│   ├── class-live-pulse-reactions.php  Post-meta based reaction counts
│   ├── class-live-pulse-rest.php       REST API routes
│   ├── class-live-pulse-display.php    Shared render markup, shortcode, auto-insert
│   └── class-live-pulse-block.php      Gutenberg block registration
├── blocks/live-pulse/
│   ├── block.json
│   ├── render.php                      Dynamic block render (reuses shared markup)
│   └── index.js                        Editor script (plain JS, no build step)
└── assets/
    ├── js/view.js                      Interactivity API store (presence + reactions)
    └── css/                            Frontend + admin styles

Why no build step?

Everything here is written to run as-is: no npm install, no webpack, no @wordpress/scripts. That's a deliberate choice — it keeps the codebase approachable to read end-to-end, and it means the Interactivity API's own runtime (already loaded by WordPress core for other blocks) is the only "framework" involved.

Known issues

  • Reactions can intermittently fail to save on some shared hosts. During testing on a free host (InfinityFree), reaction clicks sometimes don't reach the REST endpoint at all, with no console error. Presence tracking (the viewer counter) works reliably in the same environment. Suspected causes: aggressive edge caching/proxying of POST requests to /wp-json/ on some free hosts, or a stale service worker/browser cache. Not yet reproduced on standard hosting — issue reports and PRs welcome.
  • Presence "leaves" are timeout-based, not instant. Closing a tab doesn't immediately decrement the viewer count — it expires naturally after the configured presence timeout (default 30s). This is a deliberate trade-off: an instant leave via navigator.sendBeacon can't reliably carry the REST nonce needed to authenticate the request.

Contributing

Issues and pull requests are welcome. A few ideas for a v2, if you'd like to help:

  • Poll-based reactions on comments, not just posts
  • A lightweight admin dashboard showing historical peak viewers
  • An opt-in "who reacted" avatar stack for logged-in users

License

GPLv2 or later — see LICENSE.

Author

Built by Hafez FandyLinkedIn.

Read the full README on GitHub →