@prismicio/react - v2

Overview

@prismicio/react is the official Prismic package for creating web apps with Prismic and React.

The package is formerly known as 'prismic-reactjs'

@prismicio/react used to be called prismic-reactjs. The latter is now deprecated, and you can replace it with @prismicio/react. Follow our instructions to upgrade from prismic-reactjs to @prismicio/react.

Find the documentation for prismic-reactjs on npm.

Dependencies and requirements

This package can be used in projects that use React. It is compatible with React Server Components. It relies on @prismicio/client as a peer dependency.

Since this is a general-purpose React library, it can be used in setups like Vite or in more advanced frameworks that use React like Next.js and Gatsby.

Installation

Add @prismicio/react and its peer dependencies to your React project via the command line:

  • npm
  • Yarn
npm
Copy
npm install @prismicio/react @prismicio/client
Yarn
Copy
yarn add @prismicio/react @prismicio/client

Components

@prismicio/react provides a collection of components to render content from Prismic documents.

Here are all of the components and hooks:

<PrismicProvider>

We no longer recommend using <PrismicProvider>

<PrismicProvider> and its global configuration capabilities are not compatible with React Server Components.

We recommend creating your own wrapper components to configure components globally rather than using <PrismicProvider>. To create your own wrapper component, see below in the section for the component you wish to override.

The following documentation exists only to support existing applications using <PrismicProvider>.

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

A React component to provide settings for Prismic's React components, using React context. All @prismicio/react components that are children of this one will receive the specified options as defaults.

Copy
<PrismicProvider client={client} >
  {children}
</PrismicProvider>

<PrismicProvider> accepts the following props:

client

An initialized Prismic API client from the @prismicio/client package. If provided, all client hooks use this client automatically.

linkResolver

A function that takes a document from Prismic as an argument and returns the URL path for that document. See the link resolver documentation.

richTextComponents

A map or function that returns a React component for a given rich text element. See the <PrismicRichText> section for more detail.

internalLinkComponent

A component for handling internal links. See the section on <PrismicLink> for more detail.

externalLinkComponent

A component for handling external links. See the section on <PrismicLink> for more detail.

<PrismicRichText>

Copy
import { PrismicRichText } from 'prismicio/react'

A React component that renders content from a Prismic rich text or title field.

By default, HTML elements are rendered for each piece of content. For example, a heading1 block will render an <h1> HTML element. Links will use <PrismicLink> by default.

Copy
<PrismicRichText field={document.data.myRichTextField} />

A fallback prop can be provided to define what to render when the rich text or title field is empty. If a fallback prop is not provided, null is rendered by default for an empty field.

Copy
<PrismicRichText
  field={document.data.myRichTextField}
  fallback={<p>No content</p>}
/>

This component returns a React fragment with no wrapping element around the content. If you need a wrapper, add a component around <PrismicRichText>.

Copy
<article>
  <PrismicRichText field={document.data.myRichTextField} />
</article>

To customize the components that are rendered for each block type, provide a map or function that returns a component to the components prop.

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

To globally customize <PrismicRichText>, create a wrapper component with your default props. Use the wrapper component in place of @prismicio/react's version.

src/components/PrismicRichText.tsx
Copy
import { PrismicRichText as BasePrismicRichText } from '@prismicio/react'

const defaultComponents = {
  heading1: ({ children }) => (
    <h1 className="font-bold text-3xl">{children}</h1>
  ),
}

export const PrismicRichText = ({ components, ...props }) => {
  return (
    <BasePrismicRichText
      components={{ ...defaultComponents, ...components }}
      {...props}
    />
  )
}

If a different component needs to be rendered for a specific instance of <PrismicRichText>, a components prop can be provided to override the shared component mapping.

Here's an example that uses all the available field keys for the components object:

Copy
<PrismicRichText
  field={document.data.myRichTextField}
  components={{
    heading1: ({ children, key }) => <h1 key={key}>{children}</h1>,
    heading2: ({ children, key }) => <h2 key={key}>{children}</h2>,
    heading3: ({ children, key }) => <h3 key={key}>{children}</h3>,
    heading4: ({ children, key }) => <h4 key={key}>{children}</h4>,
    heading5: ({ children, key }) => <h5 key={key}>{children}</h5>,
    heading6: ({ children, key }) => <h6 key={key}>{children}</h6>,
    paragraph: ({ children, key }) => <p key={key}>{children}</p>,
    preformatted: ({ node, key }) => <pre key={key}>{node.text}</pre>,
    strong: ({ children, key }) => <strong key={key}>{children}</strong>,
    em: ({ children, key }) => <em key={key}>{children}</em>,
    listItem: ({ children, key }) => <li key={key}>{children}</li>,
    oListItem: ({ children, key }) => <li key={key}>{children}</li>,
    list: ({ children, key }) => <ul key={key}>{children}</ul>,
    oList: ({ children, key }) => <ol key={key}>{children}</ol>,
    image: ({ node, key }) => {
      const img = (
        <img
          src={node.url}
          alt={node.alt ?? undefined}
          data-copyright={node.copyright ? node.copyright : undefined}
        />
      )

      return (
        <p key={key} className='block-img'>
          {node.linkTo ? (
            <PrismicLink
              linkResolver={args.linkResolver}
              internalComponent={args.internalLinkComponent}
              externalComponent={args.externalLinkComponent}
              field={node.linkTo}
            >
              {img}
            </PrismicLink>
          ) : (
            img
          )}
        </p>
      )
    },
    embed: ({ node, key }) => (
      <div
        key={key}
        data-oembed={node.oembed.embed_url}
        data-oembed-type={node.oembed.type}
        data-oembed-provider={node.oembed.provider_name}
        dangerouslySetInnerHTML={{ __html: node.oembed.html ?? '' }}
      />
    ),
    hyperlink: ({ node, children, key }) => (
      <PrismicLink
        key={key}
        field={node.data}
        linkResolver={args.linkResolver}
        internalComponent={args.internalLinkComponent}
        externalComponent={args.externalLinkComponent}
      >
        {children}
      </PrismicLink>
    ),
    label: ({ node, children, key }) => (
      <span key={key} className={node.data.label}>
        {children}
      </span>
    ),
    span: ({ text, key }) => {
      const result: React.ReactNode[] = []

      let i = 0
      for (const line of text.split('\n')) {
        if (i > 0) {
          result.push(<br key={`${i}__break`} />)
        }
        result.push(
          <React.Fragment key={`${i}__line`}>{line}</React.Fragment>
        )
        i++
      }

      return <React.Fragment key={key}>{result}</React.Fragment>
    },
  }}
/>

<PrismicText>

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

React component that renders content from a Prismic rich text or title field as plain text.

Copy
<PrismicText field={document.data.myTitleField} />

A fallback prop can be provided to define what to render when the rich text or title field is empty. If a fallback prop is not given, null is rendered by default for an empty field.

Copy
<PrismicText field={document.data.myTitleField} fallback='Untitled' />

This component returns a React fragment with no wrapping element around the content. If you need a wrapper, add a component around <PrismicRichText>.

Copy
<h1>
  <PrismicText field={document.data.myTitleField} />
</h1>

<PrismicLink>

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

React component that renders a link from a Prismic link field or a Prismic document.

It automatically resolves a field's link to a URL. It also applies the correct target and rel props if "Open in new tab" is enabled for the field.

Copy
<PrismicLink field={document.data.myLinkField}>
  Click me
</PrismicLink>

To link to a document, use the document prop in place of the field prop.

Copy
<PrismicLink document={document}>
  Click me
</PrismicLink>

By default, an <a> HTML element is rendered for all links. If your React app requires a special <Link> component for internal links, such as one from react-router-dom, a component can be provided to the internalComponent prop. That component will automatically be rendered for internal links.

Copy
<PrismicLink
  field={document.data.myLinkField}
  internalComponent={Link}
>
  Click me
</PrismicLink>

The component for external links can similarly be overridden using the externalComponent prop.

Copy
<PrismicLink
  field={document.data.myLinkField}
  externalComponent={(props) => <a className='external' {...props} />}
>
  Click me
</PrismicLink>

To globally customize <PrismicLink>, create a wrapper component with your default props. Use the wrapper component in place of @prismicio/react's version.

src/components/PrismicLink.tsx
Copy
import { PrismicLink as BasePrismicLink } from '@prismicio/react'

const InternalLink = (props) => {
  return <a className="internal" {...props} />
}

export const PrismicLink = (props) => {
  return <BasePrismicLink internalComponent={InternalLink} {...props} />
}

If your app uses the route resolver when querying for documents, providing a link resolver is optional. If your app does not use a route resolver or requires overriding a document's URL in specific cases, a link resolver can be provided using the linkResolver prop.

Copy
<PrismicLink
  field={document.data.myLinkField}
  linkResolver={linkResolver}
>
  Click me
</PrismicLink>

<PrismicImage>

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

React component that renders an optimized image from a Prismic image field. The rendered <img> element contains a srcset with image URLs for common viewport widths.

Copy
<PrismicImage field={doc.data.myImageField} />

Are you using a framework like Next.js or Gatsby?

If you are using a framework like Next.js or Gatsby, prefer its framework-specific image integration over this <PrismicNext>. For example, use @prismicio/next's <PrismicNextImage> component or Gatsby's gatsby-plugin-image component if you are using those frameworks.

Only use <PrismicImage> if your environment does not have a built-in optimized image component.

The image CDN which Prismic serves all images through, imgix, allows image transformations using URL parameters. imgix URL parameters can be provided to <PrismicImage> using the imgixParams prop.

Copy
// Renders a grayscale image
<PrismicImage field={doc.data.myImageField} imgixParams={{ sat: -100 }} />

See imgix's Image URL API Reference for a full list of the available parameters, including saturation changes, cropping, and blurring.

The component automatically applies the image field’s alt text to the rendered <img> element. To customize the alt text, use the alt prop.

Copy
<PrismicImage field={doc.data.imageField} alt='' />

To provide a fallback alt text to be used if the image field does not contain alt text, use the fallbackAlt prop.

Copy
<PrismicImage field={doc.data.imageField} fallbackAlt='' />

Note: The alt and fallbackAlt props only accept an empty string ('') to let you declare an image as decorative. Any other value is invalid. See the alt must be an empty string” article for more details.

By default, <PrismicImage> will use the following widths in its srcset attribute: 640, 750, 828, 1080, 1200, 1920, 2048, 3840. To override these widths, use the widths prop.

Copy
<PrismicImage field={doc.data.imageField} widths={[400, 800, 1600]} />

To use a pixel density-based srcset instead, pass a set of pixel densities to the pixelDensities prop.

Copy
<PrismicImage field={doc.data.imageField} pixelDensities={[2, 4]} />

To use the built-in set of good default pixel densities, pass pixelDensities='defaults' to the component. The component uses [1, 2, 3] as its default pixel densities.

Copy
<PrismicImage field={doc.data.imageField} pixelDensities='defaults' />

<SliceZone>

Copy
import { SliceZone } from '@prismicio/react';

React component that renders content from a Prismic Slice Zone using React components for each type of Slice.

For example, if a Slice Zone contains a Text Slice followed by an Images Slice, <SliceZone> will render <TextSlice> and <ImagesSlice> in a list.

Copy
<SliceZone
  slices={document.data.body}
  components={{
    text: TextSlice,
    images: ImagesSlice,
  }}
/>

Alongside the slices prop, an object of Slice type IDs (for example: "text") mapped to its React component (for example: <TextSlice>) should be provided to the components prop.

Slice components receive four props:

  • slice: The Slice object being rendered.
  • index: The index of the Slice within the Slice Zone.
  • slices: The list of all Slice objects in the Slice Zone.
  • context: Arbitrary data passed to the <SliceZone>'s context prop.

A Slice component could look like this:

Copy
function TextSlice({ slice }) {
  return (
    <section>
      <PrismicRichText field={slice.primary.text} />
    </section>
  );
}

If you have data that needs to be shared with all Slice components, provide a value to the context prop. The data will be passed to each Slice component as a context prop.

Copy
<SliceZone
  slices={document.data.body}
  components={{
    text: TextSlice,
    images: ImagesSlice,
  }}
  context={{ foo: 'bar' }}
/>

You can then consume the prop in any Slice component defined in the components array.

Copy
function TextSlice({ slice, context }) {
  return (
    <section>
      <PrismicRichText field={slice.primary.text} />
      <p>{ context.foo }</p>
    </section>
  );
}

By default, a "TODO" component will be rendered with a warning if a component is not provided for a Slice type. To override the default component, provide a component to the defaultComponent prop. The default component is passed the same props listed above.

Copy
<SliceZone
  slices={document.data.body}
  defaultComponent={() => null}
/>

The default "TODO" component will not be rendered in production (i.e. when process.env.NODE_ENV is production).

This component returns a React fragment with no wrapping element around the list of Slice components. If you need a wrapper, add a component around <SliceZone>.

Copy
<article>
  <SliceZone
    slices={document.data.body}
    components={{
      text: TextSlice,
      images: ImagesSlice,
    }}
  />
</article>

To optimize the performance of <SliceZone>, prefer defining the components prop using a variable defined outside the component.

Copy
const components = {
  text: TextSlice,
  images: ImagesSlice,
}

function Page() {
  return (
    <SliceZone
      slices={document.data.body}
      components={components}
    />
  )
}

Upgrading from next-slicezone

<SliceZone> from @prismicio/react replaces the component from the next-slicezone package. If you are currently using next-slicezone with a resolver prop, you can still pass that prop to the updated component.

<SliceZone
  slices={document.data.body}
  resolver={({ sliceName }) => {
    switch (sliceName) {
      case 'text':
        return TextSlice

      case 'images':
        return ImagesSlice
    }
  }}
/>

The resolver prop is deprecated and will be removed in a future major release. Please upgrade to the component prop using the object format described above.

For more information about how to migrate from next-slicezone, read our next-slicezone Deprecation Guide.

<PrismicToolbar>

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

React component that injects the Prismic Toolbar into the app.

This component can be placed anywhere in the React tree. The Prismic Toolbar script will be appended to the end of the app's <body> element.

Copy
<PrismicToolbar repositoryName='repo-name' />

If your repository requires the legacy Prismic Toolbar, provide a type prop to use the legacy script. By default, type is set to "new".

Copy
<PrismicToolbar repositoryName='repo-name' type='legacy' />

Hooks

Each query method from a Prismic client, such as getAllByType() or getSingle(), is provided as a hook.

Copy
const client = prismic.createClient('example-prismic-repo')

const [documents] = useAllPrismicDocumentsByType('page', { client })
const [settingsDocument] = useSinglePrismicDocument('settings', { client })

For client-rendered pages

The hooks are designed for client-rendered React apps or pages. If you are using a React framework with server-side rendering (like Next.js) or static data fetching (like Gatsby), prefer the framework's standard data fetching practices over these hooks.

The hooks are not compatible with React Server Components. Use @prismicio/client directly in Server Components or add "use client" to components that use the hooks.

All hooks accept a client parameter which should be passed a Prismic client created with @prismicio/client. See the @prismicio/client Technical Reference for configuration options.

Copy
const client = prismic.createClient('example-prismic-repo')

const [page] = usePrismicDocumentByUID('page', 'home', { client })

Hooks return the fetching state in addition to the query result. This allows you to render, for example, a "loading" interface while the client is fetching results.

Copy
const [documents, { state, error }] = useAllPrismicDocumentsByType('page', {
  client,
})

state can be one of the following values:

  • "idle": The hook is waiting to query the repository.
  • "loading": The hook is querying the repository.
  • "loaded": The hook is done querying the repository.
  • "failed": The hook failed to query the repository.

error will contain a PrismicError object from @prismic/client if the hook fails to query the repository. The hook will be in the "failed" state.

If a hook requires specific parameters or a different client, they can be provided as an object in the last argument.

Copy
const client = prismic.createClient('example-prismic-repo')

const [documents] = useAllPrismicDocumentsByType('page', {
  client,
  lang: 'fr-fr',
})

All query hooks

Here are all of the components and hooks:

usePrismicDocuments()

See client.get()

useFirstPrismicDocument()

See client.getFirst()

useAllPrismicDocumentsDangerously()

See client.dangerouslyGetAll()

usePrismicDocumentByID()

See client.getByID()

usePrismicDocumentsByIDs() 
useAllPrismicDocumentsByIDs()

See client.getByIDs(), client.getAllByIDs()

usePrismicDocumentByUID()

See client.getByUID()

usePrismicDocumentsByUIDs()
useAllPrismicDocumentsByUIDs()

See client.getByUIDs(), client.getAllByUIDs()

useSinglePrismicDocument()

See client.getSingle()

usePrismicDocumentsByType()
useAllPrismicDocumentsByType()

See client.getByType(), client.getAllByType()

usePrismicDocumentsByTag()
useAllPrismicDocumentsByTag()

See client.getByTag()

usePrismicDocumentsBySomeTags()
useAllPrismicDocumentsBySomeTags()

See client.getBySomeTags(), client.getAllBySomeTags()

usePrismicDocumentsByEveryTag()
useAllPrismicDocumentsByEveryTag()

See client.getByEveryTag(), client.getAllByEveryTag()

usePrismicClient()

A hook that returns the Prismic client provided to <PrismicProvider> at the root of your React app.

Copy
const client = usePrismicClient()

Use this hook to call methods directly on the client. For example, getting a list of all tags can be performed like this:

Copy
function MyComponent() {
  const [tags, setTags] = React.useState()
  const client = usePrismicClient()

  React.useEffect(() => {
    client.getTags().then((tags) => setTags(tags))
  }, [client]);
}

usePrismicPreviewResolver(params)

A hook that returns the URL of a previewed document during a preview session. This hook should be used on your React app's preview resolver page.

Copy
const [resolvedURL, { state, error }] = usePrismicPreviewResolver()

The hook will automatically read the preview session's URL parameters to resolve the previewed document's URL.

If you pass a navigate option, the hook will automatically redirect the browser to the resolved URL. The navigate option should be a function that accepts a URL string and redirects the browser. Popular client-side routing libraries like React Router provide this function to you.

Copy
import { useNavigate } from 'react-router-dom'

const navigate = useNavigate()

usePrismicPreviewResolver({ navigate })

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.