Gatsby Slices + Prismic Slices

Has anyone used Gatsby Slices with Prismic slices yet?
Gatsby slices for Header(navigation) etc seems really simple. But I'm wondering if anyone has a use case for using Gatsby Slices with Prismic slices.

Ie when a Prismic Text Slice is updated on UID 'index'... gatsby slices inject that change into one page rather than rebuilding the entire page or entire site?

@angeloashmore I know you have glanced at this before, I wonder if you have managed to use if yet and can give an example of how it would be used?

Hey @thejuniperstudio, I haven't had a chance to try it out Gatsby's Slices feature yet. I'll try it out today and post an update on how it goes. :slight_smile:

Here's what I learned:

You can use Gatsby's Slices with Prismic's Slices. Although the features share a name, they serve different purposes.

Gatsby Slices

Gatsby Slices allow you to extract potentially dynamic parts of a page and only rebuild those parts when its content changes.

If a Gatsby Slice's content hasn't changed since the last build, your site will build quicker since that part didn't need to be rebuilt.

If its content has changed since the last build, Gatsby only needs to rebuild the small part and then "stitch" the resulting HTML into the static output.

Stitching static HTML into an existing page is quicker than building the whole page.

Prismic Slices

A reusable content model for a section of a page. Content writers can use the same section of a page multiple times, each with their own content.

From Gatsby's perspective, a Prismic Slice is a small part of the whole page. If any part of a Prismic Slice is edited for a page, the whole page is considered "stale" and needs to be rebuilt.

Build performance

If you combine the two features by using Gatsby Slices to render components for Prismic Slices, you may see slightly quicker build times. If you edit content for a page using a Prismic Slice, the whole page will still be invalidated and will need to be rebuilt. I believe the performance benefits of using Gatsby Slices here will be minimal, if any.

Remember that Gatsby is smart enough to only rebuild pages that have changed. If you have a site with 100 pages and only edit content for one of them, only that one page will be rebuilt.

If you have shared content used on every page, however, such as a Navigation component with content from Prismic, then editing the Navigation content will force Gatsby to rebuilt every page. That's where Slices will become most useful, as you mentioned in your comment.

How to use Gatsby Slices with Prismic Slices

If you are using @prismicio/react's <SliceZone> component, you can change your components map to use Gatsby's <Slice> component. The <Slice> component should take the place of your existing React component.

Gatsby requires that all props are statically analyzable and serializable. This isn't a problem for <SliceZone>, but defining your components will be verbose. A typical example would look like this:

// src/slices/index.js

import { Slice } from "gatsby";

import ContactForm from "./ContactForm";
import Image from "./Image";
import Quote from "./Quote";
import Text from "./Text";

export const components = {
  contact_form: ({ slice, slices, index, context }) => {
    return (
      <Slice
        alias="ContactForm"
        slice={slice}
        slices={slices}
        index={index}
        context={context}
      />
    );
  },
  image: ({ slice, slices, index, context }) => {
    return (
      <Slice
        alias="Image"
        slice={slice}
        slices={slices}
        index={index}
        context={context}
      />
    );
  },
  quote: ({ slice, slices, index, context }) => {
    return (
      <Slice
        alias="Quote"
        slice={slice}
        slices={slices}
        index={index}
        context={context}
      />
    );
  },
  text: ({ slice, slices, index, context }) => {
    return (
      <Slice
        alias="Text"
        slice={slice}
        slices={slices}
        index={index}
        context={context}
      />
    );
  },
};

Then you would pass the components object to <SliceZone>:

<SliceZone slices={prismicPage.data.slices} components={components} />

Remember to register each Prismic Slice as a Gatsby Slice. If you have a src/slices directory with a <slice-name>/index.js file, you can register them in gatsby-node.js like this:

const fs = require("node:fs/promises");

exports.createPages = async ({ actions }) => {
  const { createSlice } = actions;

  const sliceDirectory = await fs.readdir("./src/slices", {
    withFileTypes: true,
  });
  for (const sliceDirectoryEntry of sliceDirectory) {
    if (sliceDirectoryEntry.isDirectory()) {
      createSlice({
        id: sliceDirectoryEntry.name,
        component: require.resolve(
          `./src/slices/${sliceDirectoryEntry.name}/index.js`
        ),
      });
    }
  }
};

I hope that helps. If you come across any interesting insights while trying it out, it'd be great to share the knowledge with the rest of us. :slight_smile:

1 Like