Template Content

On this page, you'll learn how to template Prismic content in your Gatsby application.


Prismic React Templating

These docs use the latest version @prismicio/react. Follow the migration guide to update your project if you're still using prismic-reactjs V1.

🕙 Before reading

This page assumes that you have saved the response of your queries in a variable named document.

Intro to templating

Prismic content comes in more than a dozen field types. Most of these are fields with primitive values, like Numbers or Booleans. Others are more complex structured values, like Titles, Rich Texts, and Links.

Before starting to template your content, you need to access the data from the API response. It will depend on whether you've queried for multiple documents or a single one. Then, you might access a single data field like this:

  • Multiple documents
  • Single document
Multiple documents
Copy
documents[0].data.example_key_text 
Single document
Copy
document.data.example_key_text 

For multiple documents, it's more likely that you would loop over the results array and template each data field, like this:

Copy
<ul>
  {documents.map((item) =>{
    <li key={item.id}>
      {item.data.example_key_text}
    </li>
  })}
</ul>

Primitive value fields

These are the fields that retrieve primitive values:

  • Boolean
  • Color
  • Key Text
  • Number
  • Select
  • Date
  • Timestamp

The Date and Timestamp fields are both delivered as Strings on the API, but they can do more with a bit of parsing. You can use Gatsby's built-in date and timestamp formatting capabilities.

Once you've already learned how to retrieve fields from a query you can inject them directly into your application:

  • Boolean
  • Color
  • Key Text
  • Number
  • Select
  • Date
  • Timestamp
Boolean
Copy
<span>{document.data.example_boolean}</span>
// Output: "<span>true</span>"
Color
Copy
<span>{document.data.example_color}</span>
// Output: "<span>#a24196</span>"
Key Text
Copy
<span>{document.data.example_key_text}</span>
// Output: "<span>Lorem ipsum</span>"
Number
Copy
<span>{document.data.example_number}</span>
// Output: "<span>7</span>"
Select
Copy
<span>{document.data.example_select}</span>
// Output: "<span>Lorem</span>"
Date
Copy
<span>{document.data.example_date}</span>
// Output: "<span>2023-10-22</span>"
Timestamp
Copy
<span>{document.data.example_timestamp}</span>
// Output: "<span>2023-10-22T05:00:00+0000</span>"

Structured fields

The rest of the fields in Prismic are objects that you need to parse. Below, we'll explain how to work with the following structured fields:

  • Geopoint
  • Embed
  • Group
  • Rich Text
  • Link
  • Image

Geopoint

The GeoPoint field is an object with two properties: latitude and longitude. Access these properties directly:

Copy
const lat = document.data.example_geopoint.latitude   
const long = document.data.example_geopoint.longitude 

const text = `Coordinates for this location: Latitude ${lat}, longitude is ${long}.`
// Output: "Coordinates for this location: Latitude is 48.85392410000001, longitude is 2.2913515000000073."

Embed

You can template an Embed field using the html value from the response:

Copy
<div dangerouslySetInnerHTML={{ __html: document.data.example_embed.html }} />

// Outputs as raw html

Group

To template a Group, you can use a map() method to loop over the results. Here's a usage example:

Copy
<ul>
  {document.data.example_group.map((item) => (
    <li key={item.id}>
      {item.example_key_text}
      {item.example_number}
    </li>
  ))}
</ul>

// Outputs as a list of items

Rich Text and Titles

Rich Text and Titles are delivered in an array that contains information about the text structure. Use the richText field and the <PrismicRichText> component from the @prismicio/react kit. Or, use the text field if you want to render plain text.

  • richText
  • text
richText
Copy
import { PrismicRichText } from '@prismicio/react'

<PrismicRichText field={document.data.example_rich_text.richText} />
text
Copy
import { PrismicText } from '@prismicio/react'

<PrismicText field={document.data.example_title} />

// or

<h1>{document.data.example_title.text}</h1>

Using custom React components

To modify the output of a Rich Text field, provide a component list to override the components prop. The list of components maps an element type to its React component. Here is an example using a custom component for paragraphs.

<PrismicRichText
  field={document.data.example_rich_text}
  components={{
    heading1: ({ children }) => <Heading>{children}</Heading>,
    paragraph: ({ children }) => <p className="paragraph">{children}</p>,
  }}
/>

Learn more about customizing Rich Text output in the Core Concepts article on HTML Serializing.

Links and Content Relationships

The Link field allows you to link to an external webpage, an internal Prismic document, or an item in your Media Library (like a PDF). The Content Relationship field allows you to link specifically to an internal Prismic document.

There are two things that you might want to do with a link:

  • Link to the web (To an internal document, to an external page, or media item)
  • Pull in content from another document

Link to the web

<PrismicLink> automatically resolves your external links, but you need to use Gatsby's Link component to create links between internal pages.

Wrap your app with <PrismicProvider> in a centralized location such as the gatsby-browser.js and gatsby-ssr.js files and configure the internalLinkComponent prop to use Gatsby's <Link> for internal links made with Content Relationship fields.

Copy
// Example gatsby-browser.js and gatsby-ssr.js file

import * as React from 'react'
import { Link } from 'gatsby'
import { PrismicProvider } from '@prismicio/react'

function App({ children }) {
  return (
    <PrismicProvider
      internalLinkComponent={({ href, ...props }) => (
        <Link to={href} {...props} />
      )}
    >
      {children}
    </PrismicProvider>
  )
}

After that, pass your Link or Content Relationship field to <PrismicLink> and it will automatically render the correct route:

Copy
import { PrismicLink } from '@prismicio/react'

<PrismicLink field={document.data.example_content_relationship}>Example Link</PrismicLink>

Pull content from a linked document

To access the data from a linked document, access the document.data node from the linked doc retrieved from the query.

For example, here we have a Content Relationship field called example_content_relationship linked to another Custom Type. We retrieve a Key Text field that has an API ID of author_name:

Copy
<p> Written by: {document.data.example_content_relationship.data.author_name}</p>
// <strong>Written by: Jane Doe</strong>

Images

Image fields can have alt text, copyright, and alternate responsive views, which can also have their own alt text. If an Image field is configured with multiple sizes, its individual images can be queried using the thumbnails field. Each thumbnail within the field can be queried just like its primary image.

You can template images using an img tag, or a picture tag if you have multiple responsive thumbnail views:

  • <img/>
  • <picture/>
<img/>
Copy
<img src={document.data.example_image.url} alt={document.data.example_image.alt} />
<picture/>
Copy
<picture>
   <source
     srcSet={document.data.example_image.thumbnails.mobile.url : ''}
     alt={document.data.example_image.thumbnails.mobile.alt : ''}
     media="(max-width: 500px)"
   />
   <source
     srcSet={document.data.example_image.thumbnails.tablet.url : ''}
     alt={document.data.example_image.thumbnails.tablet.alt : ''}
     media="(max-width: 1100px)"
   />
   <img
     src={document.data.example_image.url : ''}
     alt={document.data.example_image.alt : ''}
   />
</picture>

Image processing

Images from Prismic can be automatically optimized and scaled using Gatsby's image plugin, gatsby-plugin-image.

You can process image data for gatsby-plugin-image using one of the following methods:

  • On-the-fly transformed using Imgix (recommended): Images are not downloaded to your computer or server and instead are transformed using Prismic's Imgix integration to resize images on the fly.
  • Locally transformed at build-time: Images are downloaded to your computer or server, resizing images at build-time.

You can apply image processing to any Image field and its thumbnails on a document. Image processing of inline images added to Rich Text fields is currently not supported.

Imgix transformed images

Using this method, images are manipulated on Imgix's servers at request time, eliminating the need to download and resize images on your computer or server. This results in faster build times.

You can query image data for gatsby-plugin-image's GatsbyImage component like in the following example:

Copy
query Home {
  prismicHomepage {
    data {
      example_image {
        gatsbyImageData
      }
    }
  }
}

Arguments can be passed to the gatsbyImageData field to change its presentation. See Gatsby's official documentation on the Gatsby Image plugin to learn more about the available arguments.

Locally transformed images

Using this method, images are downloaded to your computer or server and resized locally. Images are served from the same host as the rest of your app. This incurs additional build time as image processing is time-consuming.

To use local image processing, you need the following plugins in your project's gatsby-config.js:

You must list which files should be downloaded in the shouldDownloadFiles option of the plugin config in gatsby-config.js. By default, no files are downloaded. Then you can query image data for gatsby-plugin-image's GatsbyImage component like in the following example.

  • sample query
  • Sample gatsby-config.js
sample query
Copy
query Pages {
  allPrismicPage {
    nodes {
      data {
        photo {
          localFile {
            childImageSharp {
              gatsbyImageData
            }
          }
        }
      }
    }
  }
}
Sample gatsby-config.js
Copy
// Example gatsby-config.js file

module.exports = {
  plugins: [
    {
      resolve: 'gatsby-source-prismic',
      options: {
        // Alongside your other options...
        shouldDownloadFiles: {
          // Download a Page `photo` image:
          'page.data.photo': true,
        },
      },
    },
    'gatsby-plugin-image',
    'gatsby-plugin-sharp',
    'gatsby-transformer-sharp',
  ],
}

Arguments can be passed to the gatsbyImageData field to change its presentation. See Gatsby's official documentation on the Gatsby Image plugin to learn more about the available arguments.

Slices

To render Slices, use the <SliceZone> component from @prismicio/react to iterate over each Slice and pass them props to render the correct one.

The following example has two Slices: image_gallery and quote. First, we create an index.js file in a slices folder. This will gather an object with all the Slice components.

Copy
// Sample 〜/slices/index.js file
import { ImageGallerySlice } from './ImageGallerySlice'
import { QuoteSlice } from './QuoteSlice'

export const components = {
  quote: QuoteSlice,
  image_gallery: ImageGallerySlice,
}

Then, we import that file into the page where we render the SliceZone. The components prop receives the list of React components for each type of Slice and slices the Slice Zone array:

Copy
// Truncated page file example
import { SliceZone } from '@prismicio/react'
import { components } from '../slices'

onst PageTemplate = ({ data }) => {
  const pageContent = data.prismicPage

  return (
    <SliceZone slices={pageContent.data} components={components} />
  )
}

// ... 

Was this article helpful?
Not really
Yes, Thanks

Can't find what you're looking for? Spot an error in the documentation? Get in touch with us on our Community Forum or using the feedback form above.