next-slicezone
next-slicezone is deprecated
This package is deprecated. Its functionality has been redistributed to other packages. For more information, read the next-slicezone Deprecation Guide.
The next-slicezone
package exports two lifecycle hooks (useGetStaticProps
, useGetStaticPaths
) that allow you to fetch associated data of documents on Prismic and get the static paths of a given route. It also exports a component (SliceZone
) that matches your Next.js components with Prismic slices.
Together they render front-end components for each of your Prismic documents. You'll see how to use these later, but first, you should learn how to install and configure the package.
Package Version
This article refers to the latest version of the next-slicezone
package. The latest version of this package no longer requires next-transpile-modules
: See npm to check the latest version.
- npm
- Yarn
npm install next-slicezone
yarn add next-slicezone
You should also install @prismicio/client
which will be used to query the Prismic API:
- npm
- Yarn
npm install @prismicio/client@^5
yarn install @prismicio/client@^5
You will need to configure a few project files to use this package.
Create a file at the root of your project called sm.json
. This file is a configuration file for the slice-machine-ui
and your <SliceZone>
component which will use this file to find the location of your slice libraries.
Accepted Attributes
Usage
apiEndpoint
You can specify your Prismic API endpoint here and import it throughout your project.
libraries
Used to specify a slices directory (@/my-slices), nested slice directories (@/slices/new-library) or library packages (like react essential-slices).
_latest
Used to specify the version of slice-machine-ui.
storybook
Used to specify the port in which to open a storybook integration.
Example file
{
"apiEndpoint": "https://your-repo-name.cdn.prismic.io/api/v2",
"libraries": [
"@/slices",
"@/my-slices/new-library",
"essential-slices"
],
"_latest": "0.1.0",
"storybook": "http://localhost:8888"
}
The createResolver
function will generate an sm-resolver.js
file in the root of your project every time you change your slices structure (rename, add, delete a slice, add a library, etc.). This file contains the SliceResolver
function, which automatically matches slices and their content coming from Prismic to the local components in your project. You will need to import it when building a page and pass it to the <SliceZone>
component.
To do this, create a 〜/pages/_document.js
file and add the createResolver
method to its getInitialProps
method:
import Document, { Html, Head, Main, NextScript } from 'next/document'
import { createResolver } from 'next-slicezone/resolver' // import the function here
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 />
</div>
</Html>
)
}
}
Example sm-resolver.js file
This file contains the JavaScript SliceResolver
function which you need to import when building a page and pass it to the <SliceZone>
component. You can see how to do this further down the article where we discuss the <SliceZone>
.
import { Fragment } from 'react'
import * as Slices from './slices'
const __allSlices = { ...Slices, }
const NotFound = ({ sliceName, slice, i }) => {
console.error(`[sm-resolver] component "${sliceName}" not found at index ${i}.`)
console.warn(`slice data: ${slice}`)
return process.env.NODE_ENV !== 'production' ? (
<div
style={{
height: '30vh',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column',
textAlign: 'center',
background: '#FAFAFA'
}}
>
<h2>
Slice "{sliceName}" not found.
</h2>
<p style={{ maxWidth: '320px', fontSize: '16px' }}>
Check that you registered this component in your slices library!
</p>
</div>
) : <Fragment />
}
export default function SliceResolver({ sliceName, ...rest }) {
return __allSlices[sliceName] ? __allSlices[sliceName] : () => <NotFound sliceName={sliceName} {...rest} />
}
Next.js offers two data fetching functions:
getStaticProps()
which gets the data for statically-generated pages
getStaticPaths()
which determines all of the routes for statically-generated dynamic pages
next-slicezone
extends the functionality of those hooks with useGetStaticPaths()
and useGetStaticProps()
,
useGetStaticProps can be used on every page using the SliceZone. It's responsible for:
- fetching content from Prismic
- returning a pre-written Next getStaticProps
apiParams
useGetStaticProps
takes an apiParams
object or function as an argument.
The object argument allows you to specify static props to send to your query such as a language code.
The function argument gives you access to the params
, previewData
, and preview
objects to help build your queries and send dynamic data such as document UIDs from the URL bar to the query. The returned data can also be used when building static paths which you can see in the useGetStaticPaths
example below.
client
function (required)
Receives a Prismic client. Example:
Prismic.client(apiEndpoint)
apiParams
object
Object or function passed to client apiOptions. The function gives you access to the params, previewData, and preview objects. Static Object Example:
apiParams: { lang: 'fr-fr', },
queryType
string
Defines whether the custom type is a singleton or repeatable. Defaults to 'repeat'. Example:
'single'
type
string
Custom type to query. Defaults to 'page'. Example:
'blog_post'
slicesKey
string
Key of slices array in API response (doc.data.[slicesKey]) Defaults to slices. Example:
'MySliceZone'
getStaticPropsParams
extra params used by getStaticProps, like notFound or redirect. Example:
{ revalidate: true }
Hook example only
In this dynamic example below, we query a repeatable page
type by uid
from the URL.
See a full-page example further down the article.
- [uid].js (dynamic file name)
- Deprecated method (Before V0.1.0)
import Prismic from '@prismicio/client'
import { useGetStaticProps } from 'next-slicezone/hooks'
export const getStaticProps = useGetStaticProps({
client: Prismic.client('https://your-repo-name.cdn.prismic.io/api/v2'),
queryType: 'repeat',
type: 'page',
slicesKey: 'MySliceZone',
getStaticPropsParams: {
notFound: false
},
apiParams({ params }) {
// params are passed by getStaticPaths
return {
lang: params.lang,
uid: params.uid
}
}
})
export const getStaticProps = useGetStaticProps({
client: Prismic.client('https://your-repo-name.cdn.prismic.io/api/v2'),
uid: ({ params }) => params.uid
})
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 getStaticPaths
function. It will fetch content from Prismic using dynamic properties.
useGetStaticPaths
takes a params object as an argument.
client
Same as useGetStaticProps
type
Same as useGetStaticProps
apiParams
Same as useGetStaticProps
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:
formatPath: (prismicDocument) => { return { params: { uid: prismicDocument.uid } } }
Hook example only
In the example below, we will create paths for a repeatable page
type from the uid
in the recently queried Prismic document.
See a full-page example further down the article.
- [uid].js (dynamic file name)
- Deprecated method (Before V0.1.0)
import Prismic from '@prismicio/client'
import { useGetStaticProps, useGetStaticPaths } from "next-slicezone/hooks";
// Fetch content from prismic
export const getStaticProps = useGetStaticProps({
client: Prismic.client('https://your-repo-name.cdn.prismic.io/api/v2'),
type: 'page',
apiParams({ params }) {
// params are passed by getStaticPaths
return {
lang: params.lang,
uid: params.uid
}
}
})
// fetch all docs of type `page` and pass params accordingly
export const getStaticPaths = useGetStaticPaths({
client: Prismic.client('https://your-repo-name.cdn.prismic.io/api/v2'),
type: 'page',
formatPath: (prismicDocument) => {
return {
params: {
lang: prismicDocument.lang,
uid: prismicDocument.uid
}
}
}
})
export const getStaticPaths = useGetStaticPaths({
client: Prismic.client('https://your-repo-name.cdn.prismic.io/api/v2'),
type: 'page',
formatPath: ({ uid }) => ({ params: { uid } })
})
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
This allows you to pass props, like for Theme UI, to have more control of a globally available component on the page level.
Example:
Here's an example of a [uid].js
file with a slice zone component that is receiving slices, custom props for Theme UI and we've imported the sm-resolver.js
to pass to the SliceZone
component.
import Prismic from '@prismicio/client'
import SliceZone from 'next-slicezone'
import { useGetStaticProps, useGetStaticPaths } from "next-slicezone/hooks";
import resolver from '../sm-resolver'
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: Prismic.client('https://your-repo-name.cdn.prismic.io/api/v2'),
apiParams({ params }) {
return {
uid: params.uid,
}
}
})
export const getStaticPaths = useGetStaticPaths({
client: Prismic.client('https://your-repo-name.cdn.prismic.io/api/v2'),
formatPath: (prismicDocument) => {
return {
params: {
uid: prismicDocument.uid,
}
}
}
})
export default Page
Take a look at the different use cases where you can make use of the SliceZone and the Lifecycle hooks.
In this example, we query a Singleton page of type "homepage" in an index.js
file:
import Prismic from '@prismicio/client'
import SliceZone from 'next-slicezone'
import { useGetStaticProps } from 'next-slicezone/hooks'
import resolver from '../sm-resolver' // import from project root
const Page = ({ slices }) => (
<SliceZone resolver={resolver} slices={slices} />
)
export const getStaticProps = useGetStaticProps({
client: Prismic.client('https://your-repo-name.cdn.prismic.io/api/v2'),
type: 'homepage',
queryType: 'single'
})
export default Page
In this example, we dynamically query the Repeatable pages of type "post" using the uid
of each document in a [uid].js
file:
import Prismic from '@prismicio/client'
import SliceZone from 'next-slicezone'
import { useGetStaticProps, useGetStaticPaths } from 'next-slicezone/hooks'
import resolver from '../sm-resolver' // import from project root
const Post = ({ slices }) => (
<SliceZone resolver={resolver} slices={slices} />
)
export const getStaticProps = useGetStaticProps({
client: Prismic.client('https://your-repo-name.cdn.prismic.io/api/v2'),
type: 'post',
apiParams({ params }) {
return {
uid: params.uid
}
}
})
export const getStaticPaths = useGetStaticPaths({
client: Prismic.client('https://your-repo-name.cdn.prismic.io/api/v2'),
formatPath: (prismicDocument) => {
return {
params: {
uid: prismicDocument.uid
}
}
}
})
export default Post
In this example, we query a default repeatable type "page" using the uid
and lang
based in a 〜/pages/[lang]/[uid].js
file:
import Prismic from '@prismicio/client'
import SliceZone from 'next-slicezone'
import { useGetStaticProps, useGetStaticPaths } from 'next-slicezone/hooks'
import resolver from '../sm-resolver' // import from project root
const Page = ({ slices }) => (
<SliceZone resolver={resolver} slices={slices} />
)
export const getStaticProps = useGetStaticProps({
client: Prismic.client('https://your-repo-name.cdn.prismic.io/api/v2'),
apiParams({ params }) {
return {
lang: params.lang,
uid: params.uid
}
}
})
export const getStaticPaths = useGetStaticPaths({
client: Prismic.client('https://your-repo-name.cdn.prismic.io/api/v2'),
formatPath: (prismicDocument) => {
return {
params: {
uid: prismicDocument.uid,
lang: prismicDocument.lang,
}
}
}
})
export default Page
Can't find what you're looking for?
Need technical Support? Spot an error in the documentation? Get in touch with us on our Community Forum.