Fetch Data

In this article, you’ll learn how to perform queries to the Prismic API to retrieve content in your Next.js application.

Before you proceed

First, you’ll need a project with Next.js and Prismic. If you don’t have one yet, start with the setup step.

Example

Here's a basic example of a homepage document fetched from the Prismic API with Next.js's getStaticProps():

pages/index.js
Copy
import { SliceZone } from '@prismicio/react'

import { createClient } from '../prismicio'
import { components } from '../slices'

export default function Page({ page }) {
  return <SliceZone slices={page.data.slices} components={components} />
}

export async function getStaticProps({ previewData }) {
  const client = createClient({ previewData })

  const page = await client.getSingle('homepage')

  return {
    props: {
      page,
    },
  }
}

Here is an example for a dynamic page, which includes getStaticPaths():

pages/[uid].js
Copy
import { SliceZone } from '@prismicio/react'
import * as prismicH from '@prismicio/helpers'

import { createClient } from '../prismicio'
import { components } from '../slices'

export default function Page({ page }) {
  return <SliceZone slices={page.data.slices} components={components} />
}

export async function getStaticProps({ params, previewData }) {
  const client = createClient({ previewData })

  const page = await client.getByUID('page', params.uid)

  return {
    props: {
      page,
    },
  }
}

export async function getStaticPaths() {
  const client = createClient()

  const pages = await client.getAllByType('page')

  return {
    paths: pages.map((page) => prismicH.asLink(page)),
    fallback: false,
  }
}

Types of data fetching

Data fetching in Next.js can be done in different ways depending on your application’s needs:

  • Static-site generation (SSG), which we recommend in this guide
  • Server-side rendering (SSR)
  • Incremental static regeneration (ISR)
  • Client-side rendering (CSR)

Next, we’ll go over each method to highlight the differences. In all methods, the API call to Prismic is accomplished in mostly the same way. Nonetheless, we recommend static-site generation.

Static-site generation (SSG)

Static-site generation pre-renders your application’s pages whenever there’s any change to the content of your website, which produces very fast initial page loads.

Data is fetched on the server once at build time using Next.js’ getStaticProps() API. Data returned from a page’s getStaticProps() function will be passed to the page’s component as props.

This function will only run when your app is built during deploys and after content updates.

This data fetching method is recommended for Prismic sites, because your website only changes when you publish changes to your documents in Prismic. Your app will typically be set up to rebuild each time you publish content to Prismic. See Deploy your App to learn how to set this up.

Copy
import { createClient } from '../prismicio'

export async function getStaticProps({ previewData }) {
  const client = createClient({ previewData })

  const page = await client.getByUID('page', 'home')

  return {
    props: { page }, // Will be passed to the page component as props
  }
}

Server-side rendering (SSR)

Server-side rendering renders your application’s pages each time a visitor requests the page.

Data is fetched on the server using Next.js’ getServerSideProps() API. Data returned from a page’s getServerSideProps() function will be passed as props to the page’s component.

This function will run on every page request.

Copy
import { createClient } from '../prismicio'

export async function getServerSideProps({ previewData }) {
  const client = createClient({ previewData })

  const page = await client.getByUID('page', 'home')

  return {
    props: { page }, // Will be passed to the page component as props
  }
}

All examples on this page are written for static-site generation with getStaticProps(). They can be adapted to server-side rendering by changing getStaticProps() to getServerSideProps().

Incremental static regeneration (ISR)

ISR offers combination static–server combination. ISR first generates your website statically and then selectively updates pages as needed.

Next.js has two options for ISR: background ISR and on-demand ISR. Both use the same getStaticProps() function from SSG. If you want to use ISR on your website, we recommend using background ISR.

ISR is not supported in all environments, so check that you can use it with your hosting provider.

Background ISR re-runs the getStaticProps() function for each page periodically. If the data changes, Next.js will regenerate the page. If not, nothing happens.

To configure background ISR, add a revalidate property to the object returned from getStaticProps() with a value representing the number of seconds Next.js should wait before revalidating. After that time has elapsed, Next.js will revalidate the page on the next request.

Copy
  import { createClient } from '../prismicio'

  export async function getStaticProps({ previewData }) {
    const client = createClient({ previewData })

    const page = await client.getByUID('page', 'home')

    return {
      props: { page },
     revalidate: 60
    }
  }

On-demand ISR lets you manually rebuild specific pages of your website with webhooks. To learn more about how to implement on-demand ISR, read our blog post on the subject.

On-demand requires some extra effort to set up. With on-demand ISR, it's your responsibility to ensure that all pages get updated when needed. If your data appears on more than one page, your configuration can become more intricate. For instance, if you have a menu Document that appears on multiple pages, you will need to update every page that it appears on. Otherwise, your website could display stale content and broken links.

Client-side rendering (CSR)

Next.js also supports fetching data in the client (the browser), as you might do in a normal React application. The server is not involved when using this method.

Data is fetched in the client using @prismicio/react's data fetching hooks. To learn more about how to use this method, see our React documentation.

The examples on this page are written for static-site generation

All of the examples on this page are written for static-site generation. They can be adapted to server-side rendering by changing getStaticProps() to getServerSideProps().

The examples on this page do not cover client-side rendering. You can learn how to use client-side rendering with @prismicio/react in the React documentation.

Perform a query

Queries are performed using a client created by the createClient() function exported from prismicio.js.

Here’s a complete example, querying a document of type page by its UID:

Copy
// pages/[uid].js

import { createClient } from '../prismicio'

export default function Homepage({ page }) {
  return <h1>{page.uid}</h1>
}

export async function getStaticProps({ params, previewData }) {
  const client = createClient({ previewData })

  const page = await client.getByUID('page', params.uid)

  return {
    props: { page },
  }
}

createClient() is provided the previewData object from getStaticProps(). This enables Prismic’s preview support. See Preview Drafts to learn more about setting up previews.

Query helpers

Here are the most commonly-used query helper methods:

getByUID()

Copy
getByUID(type, uid)
getByUID(type, uid, params)

Queries a document from the Prismic repository with a UID and Custom Type. type refers to the API ID of the Custom Type.

Copy
const document = await client.getByUID('post', 'my-first-post')

getSingle()

Copy
getSingle(type)
getSingle(type, params)

Queries a singleton document from the Prismic repository for a specific Custom Type. type refers to the API ID of the Custom Type.

For example, here we are querying for the only document of the Custom Type homepage.

Copy
const document = await client.getSingle('homepage')

getAllByType()

Copy
getAllByType(type)
getAllByType(type, params)

Queries all documents from the Prismic repository for a specific Custom Type. type refers to the API ID of the Custom Type. This method may perform multiple network requests. It returns an array containing all matching documents from the repository.

Copy
const documents = await client.getAllByType('article')

Further Learning

There are many more methods for querying the API. All of these queries can accept params options to filter, sort, paginate and translate your query response. See them all in the @prismicio/client Technical Reference.

Use cases

Here are a few common use cases.

Fetch linked data

To pull in content from another document, you must fetch that content in your API query using the graphQuery or fetchLinks option.

With fetchLinks, reference the API ID of the Custom Type in your Content Relationship field, followed by the API ID of the specific field you want to retrieve. For example. If you have a Custom Type called "blog" that includes a Content Relationship field called example_content_relationship linked to a Custom Type called "author", you want to retrieve a field with an API ID of author_name.

Copy
export async function getStaticProps({ previewData }) {
  const client = createClient({ previewData })

  const document = await client.getByUID('blog', 'my-blog-post', {
    fetchLinks: 'author.author_name',
  })

  return {
    props: { document },
  }
}

Once you have adjusted your API query, the linked content will appear in a data object nested in the Content Relationship field:

Copy
"example_content_relationship": {
  "id": "X9C65hEAAEFIAuLo",
  "type": "blog",
  "tags": [],
  "slug": "another-page-title",
  "lang": "en-us",
  "uid": "my-blog",
  "data": {
    "author_name": "Jane Doe"
  },
  "link_type": "Document",
  "isBroken": false
}

Query a nav menu or config document

In Prismic, you can create a singleton Custom Type to store site components, like a header, footer, nav menu, or SEO configuration.

To query a singleton, use the getSingle() method with the API ID of the singleton Custom Type.

Copy
import { createClient } from '../prismicio'

export async function getStaticProps({ previewData }) {
  const client = createClient({ previewData })

  const menu = await client.getSingle('menu')

  return {
    props: { menu },
  }
}

Query one instance of a repeatable document

On repeatable documents, we recommend adding a UID field — a unique identifier. Prismic formats each document's UID so it is URL-friendly and unique to its Custom Type.

To query a specific document of a given Custom Type, like a blog post, you can use the getByUID() method. To use getByUID(), pass the UID and the API ID of the Custom Type.

Copy
import { createClient } from '../prismicio'

export async function getStaticProps({ previewData }) {
  const client = createClient({ previewData })

  const page = await client.getByUID('page', 'hello-world')

  return {
    props: { page },
  }
}

You will likely use getByUID() with a page's URL path to generate a page based on the URL. For instance, at /hello-world, you would want to display the document with the UID hello-world. Rather than hard-coding every page by its UID, in Next.js you can use dynamic URL parameters by putting the parameter's name in square brackets: pages/[uid].js. Then you can access the uid parameter and perform a query with it:

Copy
// pages/[uid].js

import { createClient } from '../prismicio'

export async function getStaticProps({ params, previewData }) {
  const client = createClient({ previewData })

  const page = await client.getByUID('page', params.uid)

  return {
    props: { page },
  }
}

This will return a document dynamically, based on the URL, so you can template a repeatable document.

Query all documents

There are three ways to get all documents.

  • You can query all documents of a certain type with getAllByType() (recommended).
  • You can query a paginated list of all documents of a certain type with getByType(). This will return a paginated response, including up to 100 documents per page.
  • To query an unpaginated list of all documents regardless of type, use dangerouslyGetAll(). Since the payload can be large, this method can cause performance issues, and it is not recommended.
Copy
import { createClient } from '../prismicio'

export async function getStaticProps({ previewData }) {
  const client = createClient({ previewData })

  const pages = await client.getAllByType('page')

  return {
    props: { pages },
  }
}

Query by language

Prismic allows you to publish your content in different languages. By default, the API will return content in your master language. To get content in a different language, add an options object with a lang option and a locale code. Here's an example of how to query the document of the type homepage in French (fr-fr).

Copy
import { createClient } from '../prismicio'

export async function getStaticProps({ previewData }) {
  const client = createClient({ previewData })

  const homepage = await client.getSingle('homepage', { lang: 'fr-fr' })

  return {
    props: { homepage },
  }
}

You can render localized content dynamically by including the language in the URL path (e.g. /fr-fr/bonjour-le-monde), like so:

Copy
// pages/[lang]/[uid].js

import { createClient } from '../prismicio'

export async function getStaticProps({ params, previewData }) {
  const client = createClient({ previewData })
  const { uid, lang } = params

  const page = await client.getByUID('page', uid, { lang })

  return {
    props: { page },
  }
}

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.