Add a live blog to WordPress: a plugin you can build today
· 4 min read
Live blogging is one of those features that sounds simple until you try to build it. You need a stream of timestamped posts, you need it to update without the reader refreshing the page, and you need an admin interface that lets you fire off a quick update in the middle of a game or meeting without leaving the browser tab. Most general WordPress plugins do not attempt this, and the few dedicated options have shrunk.
24LiveBlog was the most-used dedicated solution in the WordPress directory until it was removed in June 2026 following security concerns. The plugin that replaced it for many sites, Arena, works but requires embedding an iframe from a third-party service with its own account, its own branding, and its own terms. For a small news site or a local sports blog, neither option is especially satisfying.
The plugin described here stores everything in your WordPress database, refreshes the front end automatically by polling a lightweight endpoint, and installs with no account required. Here is the prompt.
What one build gives you
- Custom post type for live events with a title and live/ended status
- Admin meta box for posting and removing updates in real time without a page reload
- Shortcode to embed the live blog on any page or post
- Automatic front-end refresh every thirty seconds when the event is live
- All updates stored in your own WordPress database as post meta
What it does not do
- Multiple simultaneous editors contributing to the same event
- Push notifications or browser alerts when new updates are posted
- Rich media in updates: embedded tweets, video clips, or scoreboards
- Visitor comments or reactions on the live blog
- Paid or restricted access to live coverage
24LiveBlog does these. This covers the part most sites use.
The prompt
Loads into the composer so you can edit it first. Nothing is built, and nothing is charged, until you send it.
Build a WordPress plugin for live blogging. Register a custom post type live_event with the label Live Events, publicly queryable, supporting title and editor. Add a meta box labeled Live Updates to the live_event edit screen containing: a select field for live_status with options live and ended, saved to post meta on the standard save_post hook; a textarea for drafting a new update; a Post Update button that saves the new update to the front of the live_updates post meta array via an AJAX call without reloading the page; and a display of all current updates in reverse chronological order, each showing its formatted timestamp and text and a Remove button that removes that entry via AJAX and refreshes the list. Store live_updates as a JSON-encoded array in post meta, each entry an object with keys id (a uniqid string generated at save time), text, and timestamp. Register a shortcode live_blog that accepts an id attribute matching a live_event post ID and outputs the event title, a live or ended status badge, and all current updates in reverse chronological order each showing the formatted timestamp and text. Include a JavaScript block in the shortcode output that, when live_status is live, polls the AJAX endpoint every thirty seconds, compares the first id in the returned array to the first id currently rendered, and replaces the updates list without a full page reload if they differ. Register all hooks inside a function attached to plugins_loaded.
Why live blog plugins are hard to find
Most WordPress plugins are built around forms, taxonomies, or content display: none of which need to change after the page loads. Live blogging is fundamentally different. The page needs to update as the editor posts, without the reader doing anything. That requires either a push connection or a pull loop where JavaScript polls an endpoint every few seconds. Both are possible in WordPress, but polling is simpler to build and reliable enough for text-based coverage.
The third-party services fill the gap by handling the infrastructure on their end and letting you embed the result. That works until the service changes its terms, goes paid, or disappears from the directory. At that point you are left with an external dependency you cannot control.
A self-hosted solution built around post meta and a WordPress AJAX endpoint keeps everything inside your own database. It is not as sophisticated as a dedicated platform, but for a local sports blog or a council meeting thread, it is the right scope.
What the plugin does
You create a live event by publishing a new Live Event post. A meta box on the edit screen shows the current live status (live or ended) and a textarea for new updates. Click Post Update and the text is saved immediately without reloading the page. The list of updates appears below, newest first, each with a Remove button.
On the front end, the shortcode [live_blog id="123"] renders the event title, a status badge, and all current updates in reverse chronological order. When the event is marked live, the shortcode output polls the server every thirty seconds and replaces the update list if anything has changed. When the status is set to ended, polling stops.
Each update is stored as a JSON-encoded array in post meta. Every entry has a unique identifier, the text, and a timestamp. The polling compares the latest identifier against what is currently displayed and swaps in the new list only when something has changed, so the page does not flicker on every tick.
Who this is for
News sites covering local or community events: sports games, elections, council meetings, public hearings. One editor posts quick text updates from a laptop or phone; readers on the published page see them appear within thirty seconds.
Small publications that want live coverage without a subscription to a live blogging service and without embedding an external iframe that carries someone else's branding.
Sites that ran 24LiveBlog and need a self-hosted replacement that stores data on their own server with no third-party account required.
Who should use a different approach
If you have a newsroom where multiple people contribute to the same live blog at the same time, this plugin does not handle concurrent editing conflicts or permissions scoped to individual events. You would need a multi-author workflow on top of it, or a dedicated platform built for that case.
If you need push notifications, browser alerts, or delivery to a mobile app when updates are posted, polling every thirty seconds is not the right mechanism. A service-based solution handles that out of the box and is worth the subscription cost if real-time delivery matters to your readers.
If your live coverage includes a lot of rich embeds, tweets, video clips, or scoreboards, the textarea in this plugin accepts plain text. Extending it to support oEmbed or custom embed codes is a short follow-up prompt, but it is not built in.
How to build it
Paste the prompt below into Steem. The plugin downloads as a zip and installs under Plugins > Add New > Upload Plugin. Once active, create a new Live Event post, add a few updates from the meta box, then place the shortcode on any page to test the polling. Switch the status to ended to confirm that polling stops.
Two follow-ups most news sites want: 'add a headline field to each live update, displayed in bold above the update text' adds structure to longer events. 'Allow the update textarea to accept basic HTML so editors can insert links and emphasis' unlocks formatting without requiring a full rich-text editor.
Questions
- Does this work with the block editor?
Yes. The shortcode works anywhere you can add a Shortcode block, and the Live Updates meta box appears on the live event edit screen in both the classic editor and the block editor.
- Where are the updates stored?
In your WordPress database as post meta on the live event post. Nothing is sent to a third-party service. You can back them up with any standard WordPress backup plugin.
- Can more than one person post updates to the same event?
Any WordPress user with permission to edit the live event post can add updates. If you need separate contributor accounts restricted to specific events, that requires extending the plugin.
- How long does it take for readers to see a new update?
Up to thirty seconds. The front end polls every thirty seconds, so a reader may see the update immediately or after a wait of up to thirty seconds depending on where they are in the polling cycle.
- Can I embed the same live event on multiple pages?
Yes. Place [live_blog id="123"] anywhere you can use a shortcode. The same live event can appear on a dedicated live blog page, a sidebar, or inside an article.
The prompt
Loads into the composer so you can edit it first. Nothing is built, and nothing is charged, until you send it.
Build a WordPress plugin for live blogging. Register a custom post type live_event with the label Live Events, publicly queryable, supporting title and editor. Add a meta box labeled Live Updates to the live_event edit screen containing: a select field for live_status with options live and ended, saved to post meta on the standard save_post hook; a textarea for drafting a new update; a Post Update button that saves the new update to the front of the live_updates post meta array via an AJAX call without reloading the page; and a display of all current updates in reverse chronological order, each showing its formatted timestamp and text and a Remove button that removes that entry via AJAX and refreshes the list. Store live_updates as a JSON-encoded array in post meta, each entry an object with keys id (a uniqid string generated at save time), text, and timestamp. Register a shortcode live_blog that accepts an id attribute matching a live_event post ID and outputs the event title, a live or ended status badge, and all current updates in reverse chronological order each showing the formatted timestamp and text. Include a JavaScript block in the shortcode output that, when live_status is live, polls the AJAX endpoint every thirty seconds, compares the first id in the returned array to the first id currently rendered, and replaces the updates list without a full page reload if they differ. Register all hooks inside a function attached to plugins_loaded.
Steem