How to use Google LiveBlogPosting schema to improve SEO for live blogging

Create a LiveBlogPosting using Live Center

Google’s LiveBlogPosting schema protocol gives publishers a way to ensure that their live blogs are recognized by Google as “live” content rather than a standard, static blog post. Applying a live label via this structured markup, live content appears in Google’s top-results carousel when Google determines that the content is most relevant.

How to use Google LiveBlogPosting Schema with Live Center

In order to have your site appear as below:

You will need to inject a script in your page, that follows a very specific schema: 

<script type="application/ld+json">...</script>


The complete schema can be found here: https://schema.org/LiveBlogPosting


Live Center provides you with an API that returns part of the liveBlogUpdate.


The fields shown in green in the screenshot below depict what the Live Center API provides.


In order to call the endpoint /metadata, you will need to provide your tenantKey and the channelId on which you want to get information.

Route

Example

GET /api/v2/metadata/{tenantKey}/{channelId}/posts

https://api.livecenter.com/api/v2/metadata/chris/5271/posts


The number of posts you are fetching is set to 20 by default but can be changed by adding a query parameter (?count=10).

 

Example:

https://static.norkon.net/livecentermetadata/?tenantKey=chris&channelId=5271

The page can be tested here: https://search.google.com/test/rich-results


Here is an example of a client-side generated JSON/LD:

const getArticles = async(tenantKey,channelId)=>{

                var articlesRes = await fetch(`https://api.livecenter.com/api/v2/metadata/${tenantKey}/${channelId}/posts`).then(res=>res.json())

                if (!articlesRes || articlesRes.success === false) {

                    return []

                }

                return articlesRes.result;

            }

            const setJsonContent = async(id,tenantKey,channelId)=>{

                const jsonDomEl = document.getElementById(id);

                const articles = await getArticles(tenantKey, channelId);

                jsonDomEl.innerText = JSON.stringify({

                    "@context": "https://schema.org",

                    "@type": "LiveBlogPosting",

                    "@id": "http://ncstatic.azurewebsites.net/livecentermetadata/",

                    "headline": "Apple Spring Forward Event Live Blog",

                    "description": "Welcome to live coverage of the Apple Spring Forward …",

                    "about": {

                        "@type": "Event",

                        "location": {

                            "@type": "VirtualLocation",

                            "url": "http://ncstatic.azurewebsites.net/livecentermetadata/"

                        },

                        "startDate": "2015-03-09T13:00:00-07:00",

                        "endDate": "2015-03-018T13:00:00-07:00",

                        "name": "Apple Spring Forward Event",

                        "description": "Apple Spring Forward Event",

                        "organizer": {

                            "name": "Chris",

                            "url": "http://ncstatic.azurewebsites.net/livecentermetadata/"

                        },

                        "eventAttendanceMode": "https://schema.org/OnlineEventAttendanceMode",

                    },

                    "coverageStartTime": "2015-03-09T11:30:00-07:00",

                    "coverageEndTime": "2015-03-09T16:00:00-07:00",

                    "liveBlogUpdate": [...articles.map(a=>({

                        "@type": "BlogPosting",

                        "headline": a.headline,

                        "datePublished": a.datePublished,

                        "articleBody": a.articleBody

                    }))]

                })

            }




            setJsonContent(ID_OF_SCRIPT_DOM_ELEMENT, TENANT_KEY, CHANNEL_ID);