Sorry, no results found for "".

Remix > Real-time updates

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:

1
import { useQuerySubscription } from "react-datocms";
2
import { load } from '~/lib/datocms';
3
4
const BLOG_POST_QUERY = `query HomePage {
5
blogPost {
6
title
7
}
8
}`;
9
10
export async function loader() {
11
return {
12
subscription: {
13
query: BLOG_POST_QUERY,
14
initialData: await load(BLOG_POST_QUERY),
15
token: process.env.DATOCMS_READONLY_TOKEN,
16
environment: process.env.DATOCMS_ENVIRONMENT,
17
},
18
};
19
}
20
21
export default function Home({ subscription }) {
22
const { data, error, status } = useQuerySubscription(subscription);
23
24
const statusMessage = {
25
connecting: 'Connecting to DatoCMS...',
26
connected: 'Connected to DatoCMS, receiving live updates!',
27
closed: 'Connection closed',
28
};
29
30
return (
31
<div>
32
<p>Connection status: {statusMessage[status]}</p>
33
{error && (
34
<div>
35
<h1>Error: {error.code}</h1>
36
<div>{error.message}</div>
37
{error.response && (
38
<pre>{JSON.stringify(error.response, null, 2)}</pre>
39
)}
40
</div>
41
)}
42
{data && (
43
<div>{JSON.stringify(data, null, 2)}</div>
44
)}
45
</div>
46
);
47
}

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: true option only if Preview Mode is active (that is, if context.preview is true), so that only content editors will see draft content;

  • If Preview Mode is off, fill in the subscription prop with just initialData and enabled: false options, without any additional clutter.

Here's an example snippet:

1
import { load } from '~/lib/datocms';
2
3
const BLOG_POST_QUERY = `
4
query HomePage {
5
blogPost {
6
title
7
}
8
}
9
`;
10
11
export async function loader({ request }) {
12
const session = await getSession(request.headers.get('Cookie'));
13
const previewModeActive = session.has('preview');
14
15
const initialData = await load(BLOG_POST_QUERY, {
16
includeDrafts: previewModeActive,
17
});
18
19
return {
20
subscription: previewModeActive
21
? {
22
query: BLOG_POST_QUERY,
23
initialData,
24
token: process.env.DATOCMS_READONLY_TOKEN,
25
environment: process.env.DATOCMS_ENVIRONMENT,
26
includeDrafts: true,
27
}
28
: {
29
enabled: false,
30
initialData,
31
};
32
};
33
}

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:

Remix Blog
Next.js Template blog preview
Remix Blog
Publish this demo online with just three clicks in a matter of minutes.
Deploy the demo project