Real-time Updates API > How to use it

How to use it

If you want to use real-time updates on the browser, the easiest way is to use one of our libraries. They will handle all the hard-wiring for you, including reconnecting to a new subscription channel in case of network errors.

Next.js

Please take a look at our Next.js integration guide to learn how you can use the Real-time Updates API to produce instant refresh of content as soon as it gets saved into DatoCMS.

We have also prepared a step-by-step tutorial that shows how to get to live-previews of draft content, so be sure to check that out!

You can also deploy and play with the code of one of our Next.js project starters, as they both support real-time updates:

React

If you're in a React project the react-datocms package exposes a useQuerySubscription hook that makes it trivial to make any webpage updated in real-time.

For more info on all the available options, please refer to its documentation on Github:

1
import React from "react";
2
import { useQuerySubscription } from "react-datocms";
3
4
const App: React.FC = () => {
5
const { status, error, data } = useQuerySubscription({
6
query: `
7
query AppQuery($first: IntType) {
8
allBlogPosts {
9
slug
10
title
11
}
12
}`,
13
variables: { first: 10 },
14
token: "YOUR_API_TOKEN",
15
});
16
17
const statusMessage = {
18
connecting: "Connecting to DatoCMS...",
19
connected: "Connected to DatoCMS, receiving live updates!",
20
closed: "Connection closed",
21
};
22
23
return (
24
<div>
25
<p>Connection status: {statusMessage[status]}</p>
26
{error && (
27
<div>
28
<h1>Error: {error.code}</h1>
29
<div>{error.message}</div>
30
{error.response && (
31
<pre>{JSON.stringify(error.response, null, 2)}</pre>
32
)}
33
</div>
34
)}
35
{data && (
36
<ul>
37
{data.allBlogPosts.map((blogPost) => (
38
<li key={blogPost.slug}>{blogPost.title}</li>
39
))}
40
</ul>
41
)}
42
</div>
43
);
44
};

Vanilla JS

On any other JS environment you can use the datocms-listen package which exposes a generic subscribeToQuery function that encapsulates all the connection logic.

For more info on all the available options, please refer to its documentation on Github:

1
import { subscribeToQuery } from "datocms-listen";
2
3
const unsubscribe = await subscribeToQuery({
4
query: `
5
query BlogPosts($first: IntType!) {
6
allBlogPosts(first: $first) {
7
title
8
nonExistingField
9
}
10
}
11
`,
12
variables: { first: 10 },
13
token: "YOUR_TOKEN",
14
includeDrafts: true,
15
onUpdate: (response) => {
16
// response is the GraphQL response
17
console.log(update.response.data);
18
},
19
onStatusChange: (status) => {
20
// status can be "connected", "connecting" or "closed"
21
console.log(status);
22
},
23
onChannelError: (error) => {
24
// error will be something like:
25
// {
26
// code: "INVALID_QUERY",
27
// message: "The query returned an erroneous response. Please consult the response details to understand the cause.",
28
// response: {
29
// errors: [
30
// {
31
// fields: ["query", "allBlogPosts", "nonExistingField"],
32
// locations: [{ column: 67, line: 1 }],
33
// message: "Field 'nonExistingField' doesn't exist on type 'BlogPostRecord'",
34
// },
35
// ],
36
// },
37
// }
38
console.error(error);
39
},
40
});