Implementing Live Blogging in Arc XP
This playbook offers an in-depth guide for implementing live blogging in Arc XP. It details methods for both third-party integration and custom Power Ups within Composer, aiming to optimize search engine visibility, user interface control, and overall user experience.
This guide is for digital content managers, editors, and developers using Arc XP, particularly those who manage or are planning to implement live blogging features.
Prerequisites
Proficiency with Arc XP's interface and basic functionality, including Composer, content sources, custom blocks, custom embeds, tags, IFX, and PageBuilder Editor. Use the following list of resources to familiarize yourself:
Required permissions for accessing and modifying features within Arc XP.
Workflow
Third-Party Integration
A third-party solution lets you create live blog content in a third-party external system and import that content into Arc XP either through a Power Up or as raw HTML.
The content of the third-party tool is not available for SEO and site crawlers due to the third-party integration.
Pros | Cons |
---|---|
|
|
Custom Power Ups in Composer
Designing a custom Power Up solution allows you to create content entirely in Arc XP and not in a third-party tool. By having all content come through Arc XP's regular process, the content is available for crawlers and other search engines, such as Queryly.
We recommend using a subtype for a live blog, so you can:
resolve live blogs to an alternative template
remove the live blog content from section fronts and feeds like RSS, FBIA, etc.
create a targeted query
Two levels of complexity exist for this solution, based on your requirement: single author or multiple author.
Single Author
When you need to live blog, but always only with one author at a time, then the solution is very simple and would not require an IFX Integration or any other back-end work.
Requirements
Timestamp Power Up
Customizing Article Body Chain [Themes only]
Pros | Cons |
---|---|
|
|
Multiple Authors
When you need multiple authors to contribute to one live blog, the architecture becomes more complicated. The primary reason for this complexity is the limitation of Composer allowing only one contributor to edit a story at a time.
The live blog is split into multiple stories in Composer. The system creates a parent article and multiple child articles, where all children’s content is copied to the parent. The parent article is the resulting live blog that is published.
An IFX Integration performs the copying process on a child story publish. You must set up both parent and child to trigger IFX events (subtype, label).
Requirements
Timestamp Power Up
Customizing Article Body Chain [Themes only]
IFX
Pros | Cons |
---|---|
|
|
Editorial Workflow
The following steps provide an overview of the editorial workflow for a multi-author live blog scenario.
An author creates the parent story from a template and shares the Arc ID with the contributors
The contributors create child stories from a template and add the Arc ID in the live parent ID label
Contributors can add child stories at any time
To remove child story content, you must republish the story empty. Deleting the child story does not remove the content from the parent.
When you publish a child story, the following actions occur:
Composer publishes the child story
Composer copies the child story content into the parent story (the child story Arc ID and the child story author(s) are copied into the Power Up data to identify where each entry comes from)
Composer unpublishes the child story
Architecture
Most of this solution is based on regular Arc XP content and processes that are already in place. In the following diagram, you can see that only the blue entities require a customization not provided by Arc XP.
The key components of this solution are:
child stories should never be published and made publicly accessible
the parent story should not be edited while contributors are active
![]() |
IFX Event Listener
To provide more information about IFX and IFX Integration mentioned in the Architecture diagram, see Integration Framework (IFX). IFX provides updates on operations performed on stories (see IFX events), where the IFX integration must filter through and forward the event only when certain criteria are met (see IFX endpoints).
In the case of using a live blog, the criteria are:
subtype is live blog child story [
live-story-writer
]Arc ID of the parent is provided [
labels.parent_live_id.text
]
The steps inside the IFX Integration are:
fetch the parent story draft
remove all entries from the child in the parent story
inject child story ID or authors into the Timestamp Power Up
merge all child story
content_elements
and parent storycontent_elements
update
display_date
on the parentput the modified parent story draft back into Draft API
unpublish the child story
re-publish (if already published) the parent story
Common Assets In Single and Multiple Authors
Timestamp Power Up
The Timestamp Power Up is the tool that provides entry timestamps in Arc XP, dating the entries inside your live blog. The system also uses the timestamp to define when a new entry starts, allowing you on the front end to sort the entries in descending order, with each content attached to the timestamp.
UI
The Timestamp Power Up is a custom embed that contains all information you want to attach to each live entry. You add the timestamp when you create the custom embed, and you can edit the information later. The timestamp appears even when you’re not editing, so it’s always visible inline as a content element.
Unique to the Multiple Author solution is the availability of the child story Arc ID and author(s) in the ANS (see in the Data Format). Providing these items as read-only data on the Power Up helps authors to communicate necessary changes or to make the changes themselves.
Front End
Custom embeds have a specific custom_embed
subtype as a content_element
, and therefore, you must treat them individually in the front-end code. You decide how this is supposed to look and what should be included.
Data Format
The format for a custom embed is already provided in the ANS Schema for custom_embed. This schema outlines the necessary fields for Arc XP. Custom embeds contain the embed.config
field where you must store all custom data. The format of the data inside of embed.config
is up to you.
If you’re using the Multiple Author solution, the Lambda is manipulating the Timestamp Power Up data in this step, and you must take into consideration that those fields are available for the Lambda and are not already in use. Our recommendation is that the Lambda data be located in the content_element
's additional_properties
field. An example of a potential content_element
output is as follows:
{ "_id": "B25FR7E5HJGDHOYCZVVZMHOO4A", // autogenerated, unique inside of Story "type": "custom_embed", "subtype": "timestamp_powerup", // customizable in Composer settings, needs to match Lambda "additional_properties": { "livestory_child_story": "SVFJ6BKYV5FBFNEGXUOGBLYTFI" // written & used in Lambda to target copied data }, "embed": { "config": { "additional_properties": { "livestory_author": "credits.by[x].byline", // written by Lambda used in Composer/Display "livestory_child_story": "childStory._id" // written by Lambda used in Composer }, "dateTimeField": 1660041686320 // timestamp }, "id": "timestamp-6915", // required, customizable, unique inside of Story (randomized number) "url": "/" // required } },
You can add other fields based on your needs and specifications, so long as they do not interfere with the Lambda integration, if you’re using the Multiple Author solution.
Custom embeds do have rules about how they behave. Review the following resources about custom embeds:
Live Blog (display)
All previous information in this guide is about the technical and editorial interaction with the live blog, but the most important item is how you expose the live blog to your end user. As this solution requires a custom Power Up, you must provide custom code to handle the data in the front-end code.
Themes clients must fork and customize the article body chain. See Article Body – Arc Chain. One of the benefits of this solution is the content inside the live blog is the same content available in Composer, and the additional work is only to develop the new Power Up.
As this is fully custom, you can tailor the solution to your needs. We recommend the following steps:
Group live blog entries by selecting a Timestamp Power Up and all content elements until the next Timestamp Power Up
Sort live blog entries in descending order by dateTimeField, as the order is not guaranteed in Composer
Output the live blog entries by using the Timestamp Power Up as a divider to create visual groupings
Limitations
As we are not creating a standalone live blogging solution but a solution on top of existing products, you must consider the following items.
Content Elements Limit
Caching is optimized to manage up to 6 MB of content elements per story and a maximum of 300 referents on Composer. Also, if you need that many fragments in a single story, consider a “load more” or pagination solution. See How to Fetch Content.
If the live story must go beyond the limitation, you can this workaround:
Use Collections: You could create a collection specifically for live stories. By adding tags to these stories, it allows for more streamlined and performant access. This method can help distribute the load and improve the overall user experience.
Link Stories: After reaching the limit, you can add a link in a live blog fragment to take you to the new story.
Optimize Content Elements: Consider removing entries that are older than ‘X' days. You can define your optimal amount of days as long as you don’t pass the content limit. This can help in slimming down the content_elements. It's worth noting that typical users may not navigate back through thousands of fragments, so older data might not be as crucial for current performance.
Rate Limit
Everyone who uses Arc XP has a rate limit in front of the Arc XP APIs based on their expected traffic. The live blogging solution also counts toward the Draft API's rate limit. Specifically, the setup for Multiple Authors can impact the rate limit, and therefore, you should consider it.
For more background on the rate limit for Draft API, see Draft API.
Update Time
This live blogging solution is not a real-time solution, which provides the end-user with rapid updates. The base for this solution is a regular Arc XP story in Composer and is treated as such by the caching layers.
For a detailed explanation about caching, see Caching at Arc XP.
When you re-publish a live blogging story, the system triggers a cache-bust for the client-facing URL, just as with any Arc XP story. For each node between Arc XP services and the end-user, a cache-bust takes anywhere from several seconds to two minutes. After the cache-bust is complete, a user can see the updated live blogging story when they reload the page.
Parent Article
During the active time of authors contributing to the Multiple Author solution, the parent article should remain untouched. Making changes while, in the background, new drafts are being created and published by the IFX integration is risky.
Before you make changes to the parent article, you should ask the child authors to pause; otherwise, you risk losing changes or publishing half-finished changes.
Improvement Ideas (Custom)
Schema.org integration
To ensure search engines know about your ongoing and past live blogs, provide search engines with a schema. With this schema, search engines know to identify ongoing live blogs and add a “live” label to the entries. Providing the content of the story in a LiveBlogPosting and liveBlogUpdates also helps the crawlers understand the content on the page.
Here are is a link to the LiveBlogPosting from schema.org. If you scroll to the bottom, you see an example: https://schema.org/LiveBlogPosting
Client-side refetch
A great user experience is if a user can stay on the live blogging story, and the story continuously re-fetches new updates in the background. The opened story is therefore always up-to-date with the newest entries and the user doesn’t have to reload the page.
While simple in thought, this is actually complicated to achieve, and you’d have to address the issues below to develop this solution.
Raw HTML and Social Embeds
Two very common content elements in Composer are raw HTML and social embeds. Both arrive in the code as raw HTML, which you have to add in the server-side render, as they have to be available on load to actually load. This is a general HTML limitation. Any HTML you want processed must be available during load.
If the live blog contains only text elements, then raw HTML and social embeds are not a concern for you. But if you intend to use rich text content elements, then those elements work on the initial load (as they are coming through the sever-side render), but any fetched updates after do not load.
For any instance in the article body where you add raw HTML on the page, you must process to allow for asynchronous load. Using React and basic JavaScript makes this fairly simple.
By transforming the React component into a string-HTML with renderToString
from react-dom/server
and combining it with Range.createContextualFragment()
from basic JavaScript, you can combine it and append or prepend it to the article body with the HTML running.
Use this method with caution. It removes some capabilities that React is allowing, such as hydrating or re-rendering the string-HTML children.
It is also important that these elements have a unique key to not trigger a re-render on every update, which triggers the raw HTML again.
General Data Protection Regulation (GDPR)
If you are in the European Union, you must ensure your content conforms to GDPR standards. Often that is a process that happens during page load. If you add content asynchronously, you must ensure that the incoming updates are also GDPR-conforming.
Updates need to be in sync with the story itself
To ensure that the updates you continuously receive are matching the data that is available on a fresh page load, you must ensure that both instances are receiving data from the same source. In this case, you want to fetch the same data on the update that you are fetching in globalContent
(on page load), as the page load data is also being cache-busted if an update has been published.
To ensure you are receiving the same data, you cannot make a content-source
call, as you cannot match an in-code content-source
call consistently with a resolver global content-source
call, and any further changes could break your updates. The only sure way to receive the exact same data as the globalContent
call is to use the pages' globalContent
call directly by fetching the live blog with a JSON outputType
that is created on transform of the default outputType
.
To see an example that outlines how to create the JSON outputType
through a transform, see Output Type API - transform (Object).
It’s crucial to use the JSON through transform instead of a separate outputType
because a transform of an outputType
is not cached separately than the outputType
itself, which means that we are working with the exact same data as the default outputType
. That means when a page reloads or refetches, you receive the same set of data and are working off from the same cache.
No infinite re-fetch
When providing the re-fetch ability, you must provide re-fetch only during a specific period and not indefinitely. From a technical point of view, the re-fetch has no impact and does not cause any harm. But from an end-user point of view, specifically from a mobile device, it results in constant data usage, which has an impact on mobile users and constantly keeps the page active, which also drains the battery.
Duplicate Keys
When creating code in React with many components on the same level, it’s crucial to have unique keys on each component for React to handle any re-renders. If you don’t have unique keys while performing the re-fetch, you see entries out of order or duplicated or unnecessary reloads.
Pinning
If you want to highlight specific posts in your live blog, you can pin posts.
You must update the Power Up with a Boolean field to specify if the post should be pinned or not. If you pin the post, the system pulls that entry and moves it to the top. The post can stay in reverse chronological order or you can add another timestamp to the pinning functionality to allow you to have the posts in a specific order.
Share Bar and Anchor Tags
Depending on the content in your live blog and the complexity of each entry, you might want to allow users to share entries. Then, when other users click the shared URL, the system moves them to the shared entry. To implement share functionality, you need to follow the usual anchor-tag rules and extend the front-end output of the timestamp with a Share Bar.
If you have lazy loading or other asynchronous content, the coordinates change after or while the browser is moving a user to the coordinates. Alternatively, you can turn off lazy loading or add JavaScript that refreshes the coordinates after lazy or asynchronous content is loaded.
Timeline
To keep an overview of the entries created, you can create a timeline based on the timestamps in the content elements. The timeline can be a separate block to enhance the experience from the article body in the right rail (depending on the layout) or at the top of the live blog.
You can enhance the timeline by creating anchor-tags for each timestamp and teaser-text. You can have the first text-element
after the Power Up generate the teaser-text
, or you can have the Composer Power Up manually curate the teaser-text
.
Promo Block and Story Card
To promote the live blog on a homepage or section front, you can create a custom promo block or story card to tease the entries, similar to the Timeline with other visual indicators to it being live or the Live-label of Google.
This is not suited for Themes Promo Blocks.
Overline and Label
Similar to a Breaking News story that replaces the basic label and overlines on a story with the red static text, you can do the same to live blogs to promote them better and to differentiate them from other content.
This is not suited for Themes Promo Blocks or Overline Blocks.