

WP-UserOnline, who is on the site now, split into members, guests and bots
WP-UserOnline shows how many people are on your site right now, and where they are. Members are named, guests and search bots are counted, and the whole thing refreshes itself in the background without a page reload.
I spent most of my free time creating, updating, maintaining and supporting these plugins, if you really love my plugins and could spare me a couple of bucks, I will really appreciate it. If not feel free to use it without any obligations.
The simplest way is the widget. Go to WP-Admin -> Appearance -> Widgets, add the UserOnline widget to a sidebar, and pick which of the five statistics types it should show.
A classic theme can call the template tags directly instead, anywhere in sidebar.php, header.php or a template part:
<?php if ( function_exists( 'users_online' ) ) : ?>
<p>Users online: <span id="useronline-count"><?php users_online(); ?></span></p>
<?php endif; ?>
The element ids matter: useronline-count, useronline-browsing-site, useronline-browsing-page and useronline-details are what the refresh script looks for. A figure printed outside one of them is correct when the page loads and then stays where it is.
To give visitors a page of their own listing everyone online, create a page and put the shortcode in it:
[page_useronline]
Everything the plugin has is at WP-Admin -> WP-UserOnline, on three tabs: Users Online for who is here right now, Settings, and Templates for the wording of everything the plugin prints.
One block is available in the editor, under Widgets:
[page_useronline] produces.It renders on the server, so the preview in the editor is the real listing rather than an approximation, and the page updates itself while a visitor is reading it exactly as the shortcode’s does. Only one goes in a post: the listing carries its own useronline-details element and the refresh script finds it by that name.
Rendering it records nobody. Previewing the block in the editor does not add you to the figures you are previewing, however many times the preview refreshes — visitors are recorded when a page is loaded, not when the listing is drawn.
The shortcode still works and is not going anywhere. [page_useronline] behaves exactly as it always has, and a page already containing it needs no change. The block calls the same code the shortcode calls, so the two render identically — use whichever suits the page.
wp useronline list
wp useronline list --format=count
wp useronline count
The command reads and never writes. The table maintains itself — every visit purges rows that have timed out — and the admin screen offers no destructive action, so neither does the command.
GET /wp-json/useronline/v1/count
POST /wp-json/useronline/v1/visit
count reports how many are online now, the record and its date, and records nobody — so a monitoring script polling it does not appear in the figure it is reading. `visit` is the heartbeat: it records the caller and answers with one of the four views, given a `mode` of `count`, `browsing-site`, `browsing-page` or `details`, plus the `page_url` they are on.
Neither route takes a nonce, and that is deliberate. A nonce cannot authenticate a logged-out visitor: anonymous nonces come from one session every such caller shares, so requiring one would prove nothing while breaking every visitor who is not signed in. A page_url that does not resolve to this site is ignored, and a heartbeat writes nothing but the caller’s own row.
These routes are an addition. The admin-ajax.php wp_useronline action is unchanged and still supported.