Output separate slices

Describe your question/issue in detail

I have a page type (homepage) that has two slices (slides and posts) in my Next site. My goal is to be able to layout those two slices on the homepage how ever I see fit. So there could be slide block from the slices and then a newsletter signup block from a custom component and then last the posts slice. How do I achieve this using the SliceZone? It seems to just take all the slices and output them instead of allowing individual slices to be output.

Hi Douglas,

Welcome to the community :slight_smile:

I'll be happy to help, but your question is still unclear to me. Can you give me more details, maybe an illustration of the idea?

Thanks.

Hello Phil.

I ended up figuring it out. I'll illustrate still and supply my solution for future purposes.

Lets take Prismic's homepage. There are the following components:

  • hero banner
  • the video
  • companies that work with Prismic section that has logos
  • etc.

For the sake of the example, lets not get into the "why is it a Slice" or what not. That is not the point of this example. On my website, the hero banner is in Prismic as a Slice so the client can control that content. The video is not. It is a React component that I control and do not give control to the client for due to complexity. The companies and logos are in Prismic as a Slice.

Now if I use SliceZone, it will take the two slices that I have (hero banner and companies and logos) and output those two Slices from the one SliceZone. The issue is, the video needs to display between those Slices.

My solution was to take the data from the query on client.getSingle('homepage') and filter the slices by each Slice. Now I can pass each Slice into the slices prop of the SliceZone. I now control where I want the slices to display on the homepage.

I'm not sure if there is an easier way or a helper to handle this but it works very well for me. Any guidance would still be greatly appreciated.

Thank you for sharing your solution. That seems like a really good way to do it, I'd love to see your code.

The only other solution in my head would be to have a placeholder Slice in Prismic connected to the component; this way, the client can still control the position of the component on the page while not being able to edit the content of the component itself.

In the code below you will find that I fetch the data and store it in the home variable. From there, I filter home.data.slices twice to separate slides and posts Slices. I could have done that part a little more efficiently but this my fast and dirty solution for now. :sweat_smile:

From there I then output the following:

  • Masthead: a React component that is just the navigation, logo, etc.
  • First SliceZone: This will output the slides Slice
  • CompanyLogoBlock: This would be the logo block like you have on the Prismic homepage
  • Second SliceZone: This will output the posts Slice.

If anyone knows of a better way to handle this, I'd love to get some input.

Here is what my code essentially looks like:

export default async function Index() {
  const client = createClient();
  const home = await client.getSingle('homepage');
  const slides = home.data.slices.filter((item) =>
    item.primary.hasOwnProperty('homepage_slide'),
  );
  const posts = home.data.slices.filter((item) =>
    item.primary.hasOwnProperty('post_item'),
  );

  return (
    <>
      <Masthead />
      <SliceZone slices={slides} components={components} />
      <CompanyLogoBlock />
      <SliceZone slices={posts} components={components} />
    </>
  );
}
1 Like

This is a good way to handle this if you want to make sure of the position of the Slices. :slight_smile:

Thanks for sharing your code.