Live updates can be extremely useful both for content editors and the regular visitors of your app/website:
Content-editors in Draft Mode can see their work-in-progress directly in the production website, without having to refresh the page;
Visitors can immediately see new content as it gets published, allowing all kinds of real-time interactions with your website/app (ie. live-news coverage).
useQuerySubscription
hook The react-datocms
package exposes a useQuerySubscription
hook that uses our Real-time Updates API to make any Next.js page update in real-time.
We'll start with the following example, and modify it to activate real-time updates for any visitor of your website:
const PAGE_CONTENT_QUERY = `{allBlogPosts { id title }site: _site {favicon: faviconMetaTags { attributes content tag }}}`;function getPageRequest() {return { query: PAGE_CONTENT_QUERY };}export async function generateMetadata() {const data = await performRequest(getPageRequest());return toNextMetadata(data.site.favicon);}export default async function HomePage() {const data = await performRequest(getPageRequest());return <LatestBlogPosts data={data} />}
The first step is to build a <RealtimeLatestBlogPosts />
Client component, utilizing the useQuerySubscription
hook:
'use client';import { useQuerySubscription } from 'react-datocms';function RealtimeLatestBlogPosts({ subscription }) {const { data, error, status } = useQuerySubscription(subscription);return <LatestBlogPosts data={data} error={error} status={status} />;}
Then, in our page component, we can replace the <LatestBlogPosts />
component with <RealtimeLatestBlogPosts />
:
export default async function HomePage() {const pageRequest = getPageRequest();const data = await performRequest(pageRequest);return (<RealtimeLatestBlogPostssubscription={{...pageRequest,initialData: data,environment: process.env.NEXT_DATOCMS_ENVIRONMENT,token: process.env.NEXT_DATOCMS_API_TOKEN,}}/>);}
useQuerySubscription
Perhaps a more common scenario is being able to activate real-time updates not for every visitor, but only for content editors in Draft Mode, and showing also records in draft:
In this case, the page component will change a bit, as we need to check draft mode activation and either render <RealtimeLatestBlogPosts />
or <LatestBlogPosts />
:
function getPageRequest({ includeDrafts }) {return { query: PAGE_CONTENT_QUERY, includeDrafts };}export default async function HomePage() {const { isEnabled } = draftMode();const pageRequest = getPageRequest({ includeDrafts: isEnabled });const data = await performRequest(pageRequest);if (isEnabled) {return (<RealtimeLatestBlogPostssubscription={{...pageRequest,initialData: data,environment: process.env.NEXT_DATOCMS_ENVIRONMENT,token: process.env.NEXT_DATOCMS_API_TOKEN,}}/>);}return <LatestBlogPosts data={data} />}
If you want to directly see the final result, we've prepared a fully working Next.js blog, with real-time updates of draft content in Draft Mode: