next-slicezone Technical Reference


Introduction

next-slicezone provides a SliceZone component that matches your Next.js components with Prismic Slices.

Next.js offers two data fetching functionsgetStaticPaths() (which determines all of the routes for statically-generated dynamic pages) and getStaticProps() (which gets the data for statically-generated pages). next-slicezone extends the functionality of those hooks with useGetStaticPaths() and useGetStaticProps().

Package Version

This article refers to the latest version of the next-slicezone package. This version changes how information from the parameters is called, this is documented below as well as the deprecated way of doing this.

To install this run npm install next-slicezone@0.1.0-alpha.0

Dependencies and requirements

This project requires that you have the basic @prismicio/client installed and configured, as well as the basic Next.js setup.

Installation

Install the package via a package manager:

  • npm
  • Yarn
Copy
npm i next-slicezone
Copy
yarn add next-slicezone

Create a file at the root of your project called sm.json. This file will tell SliceZone where to locate your Slices. You can specify any directories or library packages (like react essential-slices) that contain slices.

Copy
{
  "libraries": [
    "@/slices", 
    "essential-slices"
  ]
}

Usage

next-slicezone exports two lifecycle hooks and one component. Together, they allow you to get all static paths of a given route, fetch associated documents on Prismic, and render Slice components for each document.

These are useGetStaticProps, useGetStaticPaths and the <SliceZone /> component.

useGetStaticProps

This method returns a function to be passed directly to Next.js's getStaticProps function. It will fetch content from Prismic, using dynamic properties if necessary.

useGetStaticProps takes a params object as an argument.

client

function (required)

Receives a Prismic client. Example:

Prismic.client(apiEndpoint)

apiParams

object

Object passed to client apiOptions. Example:

{ lang: 'fr-fr' }

body

string

Key of Slices array in API response doc.data[body]. Defaults to 'body'. Example:

'nobody'

type

string

Custom type to query. Defaults to 'page'. Example:

'blog_post'

queryType

string

Defines whether the Custom Type is a singleton or repeatable. Defaults to 'repeat'. Example:

'single'

getStaticPropsParams

object

Object passed to return object of getStaticProps. Example:

{ revalidate: true }

Deprecated values in useGetStaticProps

Previously, useGetStaticProps required lang and uid parameters, like so:

export const getStaticProps = useGetStaticProps({  
client: Client(),
uid: ({ params }) => params.uid
lang: ({ params }) => params.lang
});

Now, these values are provided inside the apiParams property:

export const getStaticProps = useGetStaticProps({
client: Client(),
queryType: 'repeat',
type: 'page',
apiParams({ params }) {
return {
lang: params.lang,
uid: params.uid,
}
},
})

useGetStaticPaths

useGetStaticPaths can be used in dynamic pages to define the static paths to be generated. It returns a function to be passed directly to Next.js's getStaticProps function. It will fetch content from Prismic using dynamic properties.

useGetStaticPaths takes a params object as an argument.

client

function (required)

Receives a Prismic client. Example:

Prismic.client(apiEndpoint)

type

string

Custom type to query. Defaults to 'page'. Example:

'blog_post'

apiParams

object

Object of client apiOptions. Example:

{ lang: 'fr-fr' }

formatPath

function (required)

Function to format the path object that must be returned from getStaticPaths in Next.js. Pass null to skip. Defaults to (doc) => null. Example:

({uid}) =>({ params:{ uid }})

Deprecated values in useGetStaticPaths

Previously useGetStaticPaths required lang and uid parameters, like so:

export const getStaticPaths = useGetStaticPaths({
client: Client(),
type: 'page',
formatPath: ({ uid }) => ({ params: { uid } })
})

Now, these values are provided inside the apiParams property:

export const getStaticPaths = useGetStaticPaths({
client: Client(),
type: 'page',
formatPath: (prismicDocument) => {
return {
params: {
uid: prismicDocument.uid
}
}
}
});

<SliceZone />

Once slices have been fetched, they must be matched with Next.js components and rendered. The SliceZone accepts data from the API (fetched by useGetStaticProps) as a prop. It also accepts a resolver, which defines how to match Prismic Slices with Next.js components.

slices

array (required)

The data components fetched from Prismic

resolver

function (required)

Resolves calls to components from the SliceZone

sliceProps

object || function

It passes custom props to the matched slices

Here's an example of a [uid].js file with a Slice Zone component that is receiving Slices, custom props and a Route Resolver that we imported from sm-resolver.js:

  • [uid].js
  • sm-resolver.js
Copy
import Prismic from '@prismicio/client'
import SliceZone from 'next-slicezone'
import { useGetStaticProps } from 'next-slicezone/hooks'
import resolver from '../sm-resolver'

// Update your-repo-name with the name of your repository.
const apiEndpoint = 'https://your-repo-name.cdn.prismic.io/api/v2'
const Client = Prismic.client(apiEndpoint, { req })

const Page = ({ slices, data }) => (
  <SliceZone
    slices={slices}
    resolver={resolver}
    sliceProps={({ slice, sliceName, i }) => ({
      theme: i % 1 ? "light" : "dark",
      alignLeft: data.keyTextTitle?.length > 35,
    })}
  />
);


export const getStaticProps = useGetStaticProps({
  client: Client(),
  apiParams({ params }) {
    return {
      uid: params.uid,
    }
  },
})

export const getStaticPaths = useGetStaticPaths({
  client: Client(),
  formatPath: (prismicDocument) => {
    return {
      params: {
        uid: prismicDocument.uid,
      },
    }
  },
})

export default Page
Copy
export const Router = {
  routes: [{"type":"page","path":"/:uid"}],

  href: (type) => {
    const route = Router.routes.find(r => r.type === type);
    return route && route.href;
  }
};

createResolver

The resolver function can be generated every time you change your Slices structure (rename, add, delete a slice, add a library, etc.). To do this, create a 〜/pages/_document.js file and add the createResolver method to its getInitialProps method:

Copy
import Document, { Html, Head, Main, NextScript } from 'next/document'
import { createResolver } from 'next-slicezone/resolver'

export default class extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    /* In development, generate an sm-resolver.js file
    that will map slices to components */
    if (process.env.NODE_ENV === 'development') {
      await createResolver()
    }
    return { ...initialProps }
  }

  render() {
    return (
      <Html>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

Examples

Take a look at the different use cases where you can make use of the SliceZone and the Lifecycle hooks.

Query by single type

In this example, we query a Singleton page of type "homepage" in an index.js file:

Copy
import Prismic from '@prismicio/client'
import SliceZone from 'next-slicezone'
import { useGetStaticProps } from 'next-slicezone/hooks'

// Update the path for your route resolver file.
import resolver from '../path-to-your-sm-resolver'

// Update your-repo-name with the name of your repository.
const apiEndpoint = 'https://your-repo-name.cdn.prismic.io/api/v2'
const Client = Prismic.client(apiEndpoint, { req })

const Page = ({ slices }) => (
  <SliceZone resolver={resolver} slices={slices} />
)

export const getStaticProps = useGetStaticProps({
  client: Client(),
  type: 'homepage', 
  queryType: 'single',
})

export default Page

Query by repeatable type

In this example, we dynamically query the Repeatable pages of type "post" using the uid of each document in a [uid].js file:

Copy
import Prismic from '@prismicio/client'
import SliceZone from 'next-slicezone'
import { useGetStaticProps, useGetStaticPaths } from 'next-slicezone/hooks'

// Update the path for your route resolver file.
import resolver from '../path-to-your-sm-resolver'

// Update your-repo-name with the name of your repository.
const apiEndpoint = 'https://your-repo-name.cdn.prismic.io/api/v2'
const Client = Prismic.client(apiEndpoint, { req })

const Post = ({ slices }) => (
  <SliceZone resolver={resolver} slices={slices} />
)

export const getStaticProps = useGetStaticProps({
  client: Client(),
  type: 'post', 
  apiParams({ params }) {
    return {
      uid: params.uid,
    }
  },
})

export const getStaticPaths = useGetStaticPaths({
  client: Client(),
  formatPath: (prismicDocument) => {
    return {
      params: {
        uid: prismicDocument.uid,
      },
    }
  },
})

export default Post

Query by language

In this example, we query a repeatable type "page" using the uid and lang based in a 〜/pages/[lang]/[uid].js file:

Copy
import Prismic from '@prismicio/client'
import SliceZone from 'next-slicezone'
import { useGetStaticProps, useGetStaticPaths } from 'next-slicezone/hooks'

// Update the path for your route resolver file.
import resolver from '../path-to-your-sm-resolver'

// Update your-repo-name with the name of your repository.
const apiEndpoint = 'https://your-repo-name.cdn.prismic.io/api/v2'
const Client = Prismic.client(apiEndpoint, { req })

const Page = ({ slices }) => (
  <SliceZone resolver={resolver} slices={slices} />
)

export const getStaticProps = useGetStaticProps({
  client: Client(),
  apiParams({ params }) {
    return {
      lang: params.lang,
      uid: params.uid,
    }
  },
})

export const getStaticPaths = useGetStaticPaths({
  client: Client(),
  formatPath: (prismicDocument) => {
    return {
      params: {
        uid: prismicDocument.uid,
        lang: prismicDocument.lang,
      },
    }
  },
})

export default Page

Was this article helpful?
Not really
Yes, Thanks

Can't find what you're looking for? Get in touch with us on our Community Forum.