Setting up Next.js Preview Mode

    If you're using getStaticProps, props will be generated at build time, which is great from a performance point of view, but not ideal when you’re writing a draft on DatoCMS and want to preview the non-published version of your content immediately on your page.

    Next.js has the feature called Preview Mode which solves this problem. Here’s an instruction on how to use it.

    Step1: Create a preview API route

    First, create a preview API route. It can have any name - e.g. pages/api/preview.js. In this API route, you need to call setPreviewData on the response object. The argument for setPreviewData should be an object, and this can be used by getStaticProps (more on this later).

    For the sake of this example, we’ll just use {}:

    // pages/api/preview.js
    export default (req, res) => {
    res.setPreviewData({});
    res.writeHead(307, { Location: '/' });
    res.end();
    }

    You can test this manually accessing the route from your browser from http://localhost:3000/api/preview. You’ll notice that you'll be redirected to the homepage, and the __prerender_bypass and __next_preview_data cookies will be set.

    Step 2: Update getStaticProps

    The next step is to update getStaticProps to support the preview mode. If you request a page which has getStaticProps with the preview mode cookies set via res.setPreviewData, then getStaticProps will be called at request time instead of at build time.

    Furthermore, it will be called with a context object where:

    • context.preview will be true.
    • context.previewData will be the same as the argument used for res.setPreviewData.
    export async function getStaticProps(context) {
    // If you request this page with the preview mode cookies set:
    //
    // - context.preview will be true
    // - context.previewData will be the same as
    // the argument used for `setPreviewData`.
    }

    In this case, we can use the https://graphql.datocms.com/preview endpoint to access records at their latest version available, instead of the currently published.

    Both endpoints offer exactly the same queries, the only thing that will change will be the returned content:

    import { request } from "../lib/datocms";
    const HOMEPAGE_QUERY = `query HomePage($limit: IntType) {
    allBlogPosts(first: $limit) {
    title
    }
    }`;
    export async function getStaticProps(context) {
    const data = await request({
    query: HOMEPAGE_QUERY,
    variables: { limit: 10 },
    preview: context.preview
    });
    return {
    props: { data }
    };
    }
    export default function Home({ data }) {
    return <div>{JSON.stringify(data, null, 2)}</div>;
    }

    You can read more details regarding preview mode in Next.js docs page.