Query Content from the CMS

To work with your content in Next, you must first query it from the Prismic API. On this page, you'll learn how to do a Prismic API query in your Next project.


There are two main ways to query the Prismic API:

  • With the SliceZone component
  • With the @prismicio/client query helper options

Below, we'll go through each of those methods in detail.

Should I use the SliceZone or the @prismicio/client Query Helper Options?

If your project makes good use of Slices and Slice Machine, then it will probably be efficient to use the SliceZone to render the main body of a page.

Otherwise, if:

  • You want to make more advanced queries,
  • You want to query menus, headers, or footers,
  • You want to query content outside of the SliceZone,

then, the @prismicio/client query helpers will probably be more efficient.

Querying with the SliceZone Component

The SliceZone component is the recommended method for querying content in Slice Machine projects. It is best for creating dynamic page layouts with Slices.

What does the SliceZone do?

  • It queries the document from your Prismic repo
  • It matches all of the Slices in the document to Slice components in Next
  • It renders all of the document's Slice components

The SliceZone takes props as parameters passed at build time by useGetStaticProps:

slices

The array data components fetched from Prismic

theme

An arbitrary object passed as prop to all slices

Resolver

A function that resolves calls to components from the SliceZone

Query Singleton Types

Sometimes, you only have one instance of a custom type. For such types, you can do a singleton query.

We need to declare the queryType as 'single' inside the useGetStaticProps method and declare the name of the type, in this case, 'homepage'.

Then the function does the query for us, and we pass the props to the SliceZone component.

Copy
// pages/index.js
import { Client } from '../prismic'
import SliceZone from 'next-slicezone'
import { useGetStaticProps } from 'next-slicezone/hooks'

import resolver from '../sm-resolver.js'

const Page = (props) => <SliceZone {...props} resolver={resolver} />

// Fetch content from prismic
export const getStaticProps = useGetStaticProps({
  client: Client(),
  queryType: ‘single’,
  type: ‘homepage’
})

export default Page

Default Type

The type name defaults to the Custom Type of page. To replace it if we simply pass your field type, for example: 'homepage'.

Query Repeatable Types by UID

It's straightforward to query a document by its UID. We only need to manually enter the UID of the document inside useGetStaticProps and then pass the ...props to the SliceZone component as you'd normally do. In this example, the UID is: 'contact-us':

Copy
import { Client } from '../prismic'
import SliceZone from 'next-slicezone'
import { useGetStaticProps } from 'next-slicezone/hooks'
import resolver from '../sm-resolver.js'

const Post = (props) => <SliceZone {...props} resolver={resolver} />

// Fetch content from prismic
export const getStaticProps = useGetStaticProps({
  client: Client(),
  uid: 'contact-us'
  type: 'post', // type defaults to 'page'
})

export default Pos

Query Repeatable Types Dynamically

Next.js generates dynamic routes for files with names wrapped in brackets, such as [uid].js. Then we use next-slicezone/hooks to import useGetStaticProps to make the dynamic queries, and useGetStaticPaths to generate the dynamic routes.

The queries are done for us. We just need to get the uid of the doc from the params in useGetStaticProps.

To create the dynamic paths for the pages, again, we pass the uid from params in useGetStaticPaths.

Copy
// pages/[uid].js
import { Client } from '../prismic'
import SliceZone from 'next-slicezone'
import { useGetStaticProps, useGetStaticPaths } from 'next-slicezone/hooks'
import resolver from '../sm-resolver.js'

const Page = (props) => <SliceZone {...props} resolver={resolver} />

// Fetch content from prismic
export const getStaticProps = useGetStaticProps({
  client: Client(),
  uid: ({ params }) => params.uid
})

export const getStaticPaths = useGetStaticPaths({
  client: Client(),
  fallback: true,// process.env.NODE_ENV === 'development',
  formatPath: ({ uid }) => ({ params: { uid }})
})

export default Page

Static Generation with Next.js

Refer to Next's Official documentation to learn more about how getStaticQuery and getStaticPaths generate pages.

Query Content outside of the SliceZone

It's straightforward to query content outside the SliceZone of your document (i.e., top-level fields); the function useGetStaticProps has already queried this data. You need to access the props; you can see how we’ve done this in the example below where we pass the data of a Key Text field called title to a <h1> tag:

Copy
import { Client } from '../prismic'
import SliceZone from 'next-slicezone'
import { useGetStaticProps, useGetStaticPaths } from 'next-slicezone/hooks'
import resolver from '../sm-resolver.js'

const Page = (props) => {
  return (
    <>
      <h1>{props.data.title}</h1>
      <SliceZone {...props} resolver={resolver} />
    </>
  )
}

export const getStaticProps = useGetStaticProps({
  client: Client(),
  uid: ({ params }) => params.uid,
})

export const getStaticPaths = useGetStaticPaths({
  client: Client(),
  formatPath: ({ uid }) => ({ params: { uid } }),
  fallback: true,
})

export default Page

Querying with the @prismicio/client Library

The @prismicio/client library contains a collection of Helper functions for querying and rendering content from the Prismic API. Here are the three most commonly-used query helper functions:

Query Singleton

Queries the API for the document of a given singleton type.

Copy
Client.getSingle(custom-type, options)

Query by UID

Queries the API for the document of a given type with a given UID.

Copy
Client.getByUID(type, uid)

Query by Type

For more specific queries, you can use Prismic's predicates. Predicates are search parameters. To get all documents of a certain type, you'd use a predicate to search for all documents where the "type" matches a given value.

Here's what that looks like:

Copy
Client.query(Prismic.Predicates.at('document.type', 'product'))

Query all Documents

To query all documents, use the query method and pass an empty string.

Copy
Client.query('')

Further Learning: Advanced Queries

These queries can accept an options object and a callback function as additional arguments, like this:

client.getByUID( custom-type, uid, options )

Furthermore, client.query() can perform extremely powerful and specific searches.

You can learn more about options, callbacks, and advanced queries in the "Advanced Queries" section of the React documentation.

In Pages

In pages, you can use Next's getStaticProps method to query the Prismic API. The Client object is retrieved from the Prismic library in your prismic.js config file. Here's an example of the Client object:

Copy
import Prismic from 'prismicio/client'

export const Client = (req = null, options = {}) => (
  Prismic.client(apiEndpoint, Object.assign({ routes: Router.routes }, options))
)

And, here's an example of what a query might look like in the file ~/pages/[uid].js:

Copy
import React from 'react'
import { Client } from "../prismic";

const Post = () => ({ posts }) {
  return (
     // Render your page component...
  )
}


export async function getStaticProps({params}) {
  const client = Client();
  const doc = (await client.getByUID('page', params.uid)

  return {
    props: {
      doc,
    },
  }
}

export async function getStaticPaths() {
  return {
    paths: [
      { params: { id: '1' } },
      { params: { id: '2' } }
    ],
    fallback: true,
  }
}

export default Post

In Components

In components, you can use Nuxt's fetch method to query the Prismic API. Note, unlike asyncData, fetch does not return data, but instead updates properties that are already initialized. Here's an example in ~/components/header.js:

Copy
import React from 'react'
import { Client } from "../prismic";

const Home = () => ({ home }) {
  return (
     // Render your page component...
  )
}


export async function getStaticProps() {
  const doc = await client.getSingle('homepage')

  return {
    props: {
      doc,
    }
  }
}

Query by Language

Prismic allows you to publish your content in different languages. By default, the API will return content in your master language.

You can make your website language dynamic by using the lang URL param to query your content by language. This is possible thanks to Next.js' Internationalized Routing and Language Detection.

Refer to the dedicated Multilingual templating documentation for more details.


Related Articles


Was this article helpful?
Not really
Yes, Thanks

Can't find what you're looking for? Get in touch with us on our Community Forum.