Previews with HOCs

How to set everything up to make Prismic previews work with High Order Components.


Previews with HOCs or Manual Previews, which one to choose?

If you've browsed the documents in this same section, you may have noticed that there are two ways of setting up previews in your project. The option you chose will depend on your needs:

  • Preview with HOCs: Choose this option for a quick and easy setup that doesn't require extra configuration. Use High Order Components to wrap your pages and templates and set up a global store to access the preview data.
  • Manual Preview: You can choose to add a manual setup if you need to customize how the preview data is stored. e.g., if you've set up Redux or such. This setup it's designed for more advanced use cases. It uses the underlying usePrismicPreview hook and mergePrismicPreviewData helper function.

Enable Previews in your repository

Start with setting up the previews in your Prismic repository, read the dedicated guide to learn how to do it, then come back.

Enable previews in your project code

The gatsby-source-prismic plugin provides ready-to-use higher-order components so you can wrap your existing pages and templates.

Enable the Prismic Toolbar (optional)

You may optionally enable the Prismic Toolbar to use it when previewing Releases and using Sharable links with your team. You can enable this by setting the prismicToolbar option in your gatsby-config.js file to true.

Copy
plugins: [
  {
    resolve: 'gatsby-source-prismic',
    options: {
      repositoryName: 'your-repo-name',
      prismicToolbar: true
    }
  }
]

Add the PreviewStoreProvider wrapper

Wrap your application with the PreviewStoreProvider component. Create the following two files at the root of your project:

  1. gatsby-ssr.js
  2. gatsby-browser.js

Then, please copy the following code and paste it into each of the new files (Yes, it is the same code for both files, following Gatsby's recommendation).

Copy
import * as React from 'react'
import { PreviewStoreProvider } from 'gatsby-source-prismic'

export const wrapRootElement = ({ element }) => (
  <PreviewStoreProvider>{element}</PreviewStoreProvider>
)

Add the withPreview HOC

The withPreview HOC automatically merges preview data with Gatsby's static data in the data page prop. To use it, wrap the export default of your pages with withPreview as shown in the following examples.

  • src/templates/page.js
  • src/pages/index.js
Copy
import * as React from 'react'
import { graphql } from 'gatsby'
import { withPreview } from 'gatsby-source-prismic'

const PageTemplate = ({ data }) => (
  <div>
    <h1>{data.prismicPage.data.title.text}</h1>
  </div>
)

export const query = graphql`
  query PageTemplate($uid: String!) {
    prismicPage(uid: { eq: $uid }) {
      data {
        title {
          text
        }
      }
    }
  }
`
export default withPreview(PageTemplate)
Copy
import * as React from 'react'
import { graphql } from 'gatsby'
import { withPreview } from 'gatsby-source-prismic'

const Homepage = ({ data }) => (
  <div>
    <h1>{data.prismicHomepage.data.title.text}</h1>
  </div>
)

export const query = graphql`
  query homepage {
    prismicHomepage {
      data {
        title {
          text
        }
      }
    }
  }
`
export default withPreview(Homepage)

Add the withPreviewResolver HOC

You need a preview.js page that uses the withPreviewResolver HOC. That way, when an editor clicks the Preview button in Prismic, the browser is redirected to the preview resolver page configured in your Prismic preview repository settings. This page then determines the previewed document's URL and redirects to that page while storing the preview data.

withPreviewResolver accepts the same options as usePrismicPreview, which requires at least your repository name. If you use a Link Resolver in gatsby-config.js, be sure to provide it here as well.

To use withPreviewResolver, create a dedicated preview resolver page, such as src/pages/preview.js, and wrap the export default with withPreviewResolver as shown here:

Copy
import * as React from 'react'
import { withPreviewResolver } from 'gatsby-source-prismic'
import { linkResolver } from '../example_path_to_linkResolver'
import { Layout } from '../components/Layout'

const PreviewPage = ({ isPreview, isLoading }) => {
  const previewText = isPreview ? 'Loading' : 'Not a preview!'
  return (
    <Layout>
      <p>{previewText}</p>
    </Layout>
  )
}

export default withPreviewResolver(PreviewPage, {
  repositoryName: 'your-repo-name',
  linkResolver,
})

⚠️ Update the repositoryName

Make sure that you update the repositoryName to match the URL of the Prismic repository created earlier in this article. To find this, go to your Prismic dashboard, then to your repository.

If the URL for your repository is https://my-awesome-repository.prismic.io, you'll need to replace 'your-repo-name' above with 'my-awesome-repository'.

Add the withUnpublishedPreview HOC

The withUnpublishedPreview HOC provides a way to preview unpublished documents. It should be used on a page that can accept any non-existent URL, such as your 404 page. If the HOC detects that the user is previewing a page, the correct template is displayed. If not, the HOC skips its logic and renders the page as normal. In the case of a 404 page, it would continue to render your "Page Not Found" message.

The template to render is determined using the templateMap option which maps a Prismic Custom Type ID to a component.

Create a 404 page at src/pages/404.js, and wrap the export default with withUnpublishedPreview like so:

Copy
import * as React from 'react'
import { withUnpublishedPreview } from 'gatsby-source-prismic'
import { PageTemplate } from '../templates/PageTemplate'
import { BlogPostTemplate } from '../templates/BlogPostTemplate'
import { Layout } from '../components/Layout'

const NotFoundPage = () => (
  <Layout>
    <h1>Page not found!</h1>
  </Layout>
)

// If an unpublished `page` document is previewed, PageTemplate will be rendered.
export default withUnpublishedPreview(NotFoundPage, {
  templateMap: {
    page: PageTemplate,
    blog_post: BlogPostTemplate,
  },
})

⚠️ Update your page templates

Make sure that you update the templateMap to match the page templates of your project. Usually, these are under /pages or /templates.

Integrate your project with Gatsby Cloud (optional)

With Gatsby Cloud you can have access to great features, such as:

  • Real-time previews
  • Incremental builds
  • Lighthouse reports & getting instant feedback on site performance.
  • Flexible deployment options

Now your project is all set to use Previews, continue to read the dedicated guide starting from step 2. Create a Release to learn all the steps to achieve this integration:

Limitations

Unpublished documents with Gatsby Cloud

If you're using Gatsby Cloud, unpublished documents will only be preview-able when added to a release. Any other integration, like Netlify, should work as normal.

Shareable links

As for now, the shareable link functionality isn't fully unsupported when using Gatsby, you'll only be able to see the correct document by clicking the toolbar and clicking on the corresponding page you're trying to preview, otherwise it will appear as a blank page. See the open issue in github.

Aliases

GraphQL aliases are not supported since previews do not have access to your Gatsby GraphQL query. This means that if you perform anything like this in your GraphQL queries:

Copy
query {
  prismicPage(uid: { eq: $uid }) {
    uid
    data {
      myAliasedTitle: title {
        text
      }
    }
  }
}

Previews will not function properly since previewData will not change title to myAliasedTitle.

useStaticQuery

The queries made in components using useStaticQuery won't work properly when you try to build your project. We recommend you to use Fragments instead.