Home
Real-time Updates API⁡𝅶‍‍𝅺⁡‍𝅴⁡𝅴𝅹‍‍⁢𝅵‍‍⁣‌⁡⁣𝅺⁢𝅸⁡⁢‍𝅹⁢𝅺𝅸‍‍‍𝅷‍‍𝅳⁡‍⁠‍‍⁢𝅵‍‍𝅳⁡⁣⁡⁣⁡​⁡⁢⁢𝅵‍𝅺‍𝅺⁢𝅸⁡⁢‍𝅹⁣‌⁡⁣𝅺⁢𝅸⁡⁢‍𝅹⁢𝅺𝅸‍𝅺⁠⁣𝅴⁡⁣𝅺⁡‍‍𝅺𝅴⁡⁣⁠𝅸⁠𝅺⁡⁣⁡𝅴⁡​⁠⁡⁢‍𝅺⁢𝅳⁢‌⁢​⁢𝅴⁢‍⁢⁠‍𝅺𝅴⁡⁣⁠𝅸⁡⁢‍𝅺⁢⁢⁢𝅴⁢𝅳⁢⁢⁢‌⁢⁡⁢𝅴⁢​‍‍⁡𝅸

    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:

    import React from "react";
    import { useQuerySubscription } from "react-datocms";
    const App: React.FC = () => {
    const { status, error, data } = useQuerySubscription({
    query: `
    query AppQuery($first: IntType) {
    allBlogPosts {
    slug
    title
    }
    }`,
    variables: { first: 10 },
    token: "YOUR_API_TOKEN",
    });
    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 && (
    <ul>
    {data.allBlogPosts.map((blogPost) => (
    <li key={blogPost.slug}>{blogPost.title}</li>
    ))}
    </ul>
    )}
    </div>
    );
    };

    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:

    import { subscribeToQuery } from "datocms-listen";
    const unsubscribe = await subscribeToQuery({
    query: `
    query BlogPosts($first: IntType!) {
    allBlogPosts(first: $first) {
    title
    nonExistingField
    }
    }
    `,
    variables: { first: 10 },
    token: "YOUR_TOKEN",
    includeDrafts: true,
    onUpdate: (response) => {
    // response is the GraphQL response
    console.log(update.response.data);
    },
    onStatusChange: (status) => {
    // status can be "connected", "connecting" or "closed"
    console.log(status);
    },
    onChannelError: (error) => {
    // error will be something like:
    // {
    // code: "INVALID_QUERY",
    // message: "The query returned an erroneous response. Please consult the response details to understand the cause.",
    // response: {
    // errors: [
    // {
    // fields: ["query", "allBlogPosts", "nonExistingField"],
    // locations: [{ column: 67, line: 1 }],
    // message: "Field 'nonExistingField' doesn't exist on type 'BlogPostRecord'",
    // },
    // ],
    // },
    // }
    console.error(error);
    },
    });