Define Paths

Defining dynamic routes is an essential part of building a website with a CMS. As your content creators begin to add their new pages, the web app will need to create URL paths to hit those pages. That’s where routing comes in.

Routing in Next.js

Next.js’ getStaticPaths() function is called once when your project is built. It will need to know all the possible routes for a page, so using the Prismic client’s getAllByType() query and the asLink() function, we can quickly get all the documents of a Custom Type and return that information from the Prismic API to build those paths.

Next.js routes are defined using file and directory names in the pages directory, as we’ll demonstrate on this page. You can learn more about Next.js routes in their documentation.

Server-side Rendering

The examples on this page are for static-site generation (SSG). For server-side rendering (SSR) it works the same way as SSG, but without getStaticPaths(). The parameters in getServerSideProps() will contain parameters derived from the page’s URL.

Basic Link Resolver Example

If your route is something like a dynamic page at the base of your pages directory using the UID as the URL, then you query that Custom Type and map each document to get the UID and build the dynamic paths. See all use cases for the Link Resolver.

In your project’s prismicio.js file, export a Link Resolver function. The following code exports a basic Link Resolver function for a Custom Type called a page.

Copy
// ~/prismicio.js

//Imports
import * as prismic from '@prismicio/client'
import * as prismicH from '@prismicio/helpers'
import * as prismicNext from '@prismicio/next'
import sm from './sm.json'

/**
 * The project's Prismic repository name.
 */
export const repositoryName = new URL(sm.apiEndpoint).hostname.split(".")[0]

/**
 * The project's Prismic Link Resolver. This function determines the URL for a given Prismic document.
 *
 * @type {prismicH.LinkResolverFunction}
 */
export const linkResolver = (doc) => {
  if (doc.type === 'page') {
    return `/${doc.uid}`;
  }

  return '/'
}

/**
 * Creates a Prismic client for the project's repository. The client is used to
 * query content from the Prismic API.
 *
 * @param config {prismicNext.CreateClientConfig} - A configuration object to
 */
export const createClient = (config = {}) => {
  const client = prismic.createClient(sm.apiEndpoint)

  prismicNext.enableAutoPreviews({
    client,
    previewData: config?.previewData,
    req: config?.req,
  })

  return client
}

The Prismic Helper function asLink() is used inside the getStaticPaths() function to build the dynamic path:

pages/[uid].js
Copy
import { createClient, linkResolver } from '../prismicio'
import * as prismicH from '@prismicio/helpers';

export async function getStaticPaths() {
  const client = createClient()
  const documents = await client.getAllByType('page')
  return {
    paths: documents.map((doc) => prismicH.asLink(doc, linkResolver)),
    fallback: true,
  }
}

Example output URL: /about

Advanced Route Resolver nested example

For advanced nested routes, use Prismic’s Route Resolver. It gets the routes through the API with Content Relationships and returns these routes predefined in a field called url and the top level of the document.

In your project’s prismicio.js file, define a Route Resolver (routeResolver). The following code defines an advanced Route Resolver function for Custom Types called post and home-page. This is then passed to the createClient() function to get the routes when documents are queried.

Copy
// ~/prismicio.js

//Imports
import * as prismic from '@prismicio/client'
import { enableAutoPreviews } from '@prismicio/next'
import smConfig from './sm.json'

// -- Prismic Repo API Endpoint
export const endpoint = smConfig.apiEndpoint

// -- Prismic Repo Name //Regex to get repo ID
export const repositoryName = new URL(endpoint).hostname.split('.')[0]

const routeResolver = {
  routes: [
    {
      type: 'page',
      path: '/:lang/:section/:category/:uid',
      resolvers: {
        category: 'category', // API ID of the content relationship in the Custom Type
        section: 'category.section'
      }
    },
    {
      "type":"home-page",
      "path":"/:lang"
    },
  ],
}

// -- @prismicio/client initialisation
// Initialises the Prismic Client that's used for querying the API and passes it any query options.
export const createClient = (config) => {
  const client = prismic.createClient(sm.apiEndpoint, {routes: routeResolver.routes})

  enableAutoPreviews({
    client,
    context: config?.context,
    req: config?.req,
  })

  return client;
}

The examples below show how you would define your getStaticPaths() function when using the Route Resolver, it uses the Prismic Helper function asLink() to build the paths:

  • Using Next.js’ ‘Catch all dynamic routes’ method
  • Defined folder structure
Using Next.js’ ‘Catch all dynamic routes’ method
Copy
// ~/pages/[[...uid]].js

import { createClient } from '../prismicio'
import * as prismicH from '@prismicio/helpers'

// Fetch content from prismic
export async function getStaticProps({ params, previewData }) {

  const client = createClient({previewData})
  const uid = context.params.uid[params.uid.length -1]
  /* 
   * `params.uid` contains an array of each part of the URL separated by a `/`. 
   * In this example, the last part is the document's UID. 
   */

  const doc = await client.getByUID('page', uid) || {}

  return {
    props: {
      slices: doc.data.body
    }
  }
}
//Define Paths
export async function getStaticPaths() {
  const client = createClient()

  const documents = await client.getAllByType('page')

  return {
    paths: documents.map((doc) => prismicH.asLink(doc)),
    fallback: true,
  }
}
Defined folder structure
Copy
// ~/pages/[lang]/[section]/[category]/[uid].js

import { createClient } from '../prismicio'
import * as prismicH from '@prismicio/helpers'

// Fetch content from prismic
export async function getStaticProps({ params, previewData }) {
  const client = createClient({ previewData })
  const doc = await client.getByUID('page', params.uid) || {}

  return {
    props: {
      slices: doc.data.body
    }
  }
}
//Define Paths
export async function getStaticPaths() {
  const client = createClient()
  const documents = await client.getAllByType('page')

  return {
    paths: documents.map((doc) => prismicH.asLink(doc)),
    fallback: true,
  }
}

Example output URL: /en-us/group/collection/about


Was this article helpful?
Not really
Yes, Thanks

Can't find what you're looking for? Spot an error in the documentation? Get in touch with us on our Community Forum or using the feedback form above.