Real-time updates
Live updates can be extremely useful both for content editors and the regular visitors of your app/website:
Content-editors in Preview Mode can see drafts 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).
Inside a Remix project, it's extremely easy to use our Real-time Updates API to perform such changes, as it only involves adding a React hook to your page components.
How to use the useQuerySubscription hook
The react-datocms package exposes a useQuerySubscription hook that makes it trivial to update any Remix page in real-time.
The hook works by streaming any changes present to the response of a GraphQL query directly to the browser, and it a loader responsibility to prepare an object compatible with the options of the hook itself.
The following code shows a complete example that activates real-time updates for any visitor of your website:
import { useQuerySubscription } from "react-datocms";import { load } from '~/lib/datocms';
const BLOG_POST_QUERY = `query HomePage { blogPost { title }}`;
export async function loader() { return { subscription: { query: BLOG_POST_QUERY, initialData: await load(BLOG_POST_QUERY), token: process.env.DATOCMS_READONLY_TOKEN, environment: process.env.DATOCMS_ENVIRONMENT, }, };}
export default function Home({ subscription }) { const { data, error, status } = useQuerySubscription(subscription);
const statusMessage = { connecting: 'Connecting to DatoCMS...', connected: 'Connected to DatoCMS, receiving live updates!', closed: 'Connection closed', };
return ( <div> <p>Connection status: {statusMessage[status]}</p> {error && ( <div> <h1>Error: {error.code}</h1> <div>{error.message}</div> {error.response && ( <pre>{JSON.stringify(error.response, null, 2)}</pre> )} </div> )} {data && ( <div>{JSON.stringify(data, null, 2)}</div> )} </div> );} Preview Mode + useQuerySubscription
Another common scenario is being able to activate real-time updates of draft content only for content editors that are signed-in to the website via Preview Mode:
In this case, you don't want to expose your API token or pass down additional arguments to regular users, so:
Make sure to pass the
includeDrafts: trueoption only if Preview Mode is active (that is, ifcontext.previewis true), so that only content editors will see draft content;If Preview Mode is off, fill in the
subscriptionprop with justinitialDataandenabled: falseoptions, without any additional clutter.
Here's an example snippet:
import { load } from '~/lib/datocms';
const BLOG_POST_QUERY = ` query HomePage { blogPost { title } }`;
export async function loader({ request }) { const session = await getSession(request.headers.get('Cookie')); const previewModeActive = session.has('preview');
const initialData = await load(BLOG_POST_QUERY, { includeDrafts: previewModeActive, });
return { subscription: previewModeActive ? { query: BLOG_POST_QUERY, initialData, token: process.env.DATOCMS_READONLY_TOKEN, environment: process.env.DATOCMS_ENVIRONMENT, includeDrafts: true, } : { enabled: false, initialData, }; };}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 Preview Mode: