Rendering Slices

The Slices field is used to define a dynamic zone for richer page layouts.

Before Reading

This page assumes that you have already imported the prismic-reactjs library as shown below.

import {Link, RichText, Date} from 'prismic-reactjs';

This page also assumes that you have retrieved your content and stored it in a state variable named document.

It is also assumed that you have imported a Link Resolver with the variable name linkResolver. To learn more about this, check out the Link Resolving page. 

Example 1

Here is a simple example that shows how to add slices to your templates. In this example, we have two slice options: a text slice and an image gallery slice.

Text slice

The "text" slice is simple and only contains one field, which is non-repeatable.

Primary

non-repeatable

- A Rich Text field with the API ID of "rich_text"

Items

repeatable

None

The "image_gallery" slice contains both repeatable and non-repeatable fields.

Primary

non-repeatable

- A Title field with the API ID of "gallery_title"

Items

repeatable

- An Image field with the API ID of "gallery_image"

Integration

Here is an example of how to integrate these slices into a blog post. In this case, the Slice field has the API ID of body.

Copy
render() {
  if (this.state.document) {
    const document = this.state.document;

    const blogContent = document.data.body.map(function(slice, index){

      // Render the right markup for the given slice type

      // Text Slice
      if (slice.slice_type === 'text') {
        return RichText.render(slice.primary.rich_text, linkResolver);

      // Image Gallery Slice
      } else if (slice.slice_type === 'image_gallery') {
        const galleryContent = slice.items.map(function(image, imageIndex){
          return <img src={image.gallery_image.url} alt={image.gallery_image.alt} key={imageIndex}/>;
        });
        return (
          <div className="image-gallery" key={index}>
            <h2 className="gallery-title">
              {RichText.asText(slice.primary.gallery_title)}
            </h2>
            {galleryContent}
          </div>
        );

      // Return null by default
      } else {
        return null;
      }
    });

    return (
      <div className="blog-content">
        {blogContent}
      </div>
    );
  } else {
    return null;
  }
}

Example 2

The following is a more advanced example that shows how to use Slices for a landing page. In this example, the Slice choices are FAQ question/answers, featured items, and text sections.

FAQ slice

The "faq" slice is takes advantage of both the repeatable and non-repeatable slice sections.

Primary

non-repeatable

- A Title field with the API ID of "faq_title"

Items

repeatable

- A Title field with the API ID of "question"

- A Rich Text field with the API ID of "answer"

The "featured_items" slice contains a repeatable set of an image, title, and summary fields.

Primary

non-repeatable

None

Items

repeatable

- An Image field with the API ID of "image"

- A Title field with the API ID of "title"

- A Rich Text field with the API ID of "summary"

Text slice

The "text" slice contains only a Rich Text field in the non-repeatable section.

Primary

non-repeatable

- A Rich Text field with the API ID of "rich_text"

Items

repeatable

None

Integration

Here is an example of how to integrate these slices into a landing page. In this case, the Slice field has an API ID of body.

Copy
render() {
  if (this.state.document) {
    const document = this.state.document;

    const pageContent = document.data.body.map(function(slice, index){

      // Render the right markup for the given slice type

      // FAQ Slice
      if (slice.slice_type === 'faq') {
        const faqContent = slice.items.map(function(faq, faqIndex){
          return(
            <div key={faqIndex}>
              {RichText.render(faq.question, linkResolver)}
              {RichText.render(faq.answer, linkResolver)}
            </div>
          );
        });
        return(
          <div className="faq" key={index}>
            {RichText.render(slice.primary.faq_title, linkResolver)}
            {faqContent}
          </div>
         );

      // Featured Items Slice
      } else if (slice.slice_type === 'featured_items') {
        const featuredContent = slice.items.map(function(featuredItem, featuredIndex){
          return (
            <div key={featuredIndex}>
              <img src={featuredItem.image.url} alt={featuredItem.image.alt}/>
              {RichText.render(featuredItem.title, linkResolver)}
              {RichText.render(featuredItem.summary, linkResolver)}
            </div>
          );
        });
        return (
          <div className="featured-items" key={index}>
            {featuredContent}
          </div>
        );

      // Text Slice
      } else if (slice.slice_type === 'text') {
        return (
          <div className="text" key={index}>
            {RichText.render(slice.primary.rich_text, linkResolver)}
          </div>
        );

      // Return null by default
      } else {
        return null;
      }
    });

    return (
      <div className="page-content">
        {pageContent}
      </div>
    );
  }
  return null;
}