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.

prismicio.js
Copy
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 = prismic.getRepositoryName(sm.apiEndpoint)

/**
 * 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} - Configuration for the Prismic client.
 */
export const createClient = (config = {}) => {
  const client = prismic.createClient(sm.apiEndpoint, config)

  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 * as prismicH from '@prismicio/helpers'
import { createClient, linkResolver } from '../../prismicio'

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.

prismicio.js
Copy
import * as prismic from '@prismicio/client'
import * as prismicNext from '@prismicio/next'
import sm from './sm.json'

/**
 * The project's Prismic repository name.
 */
export const repositoryName = prismic.getRepositoryName(sm.apiEndpoint)

/**
 * The project's Prismic Route Resolver. These objects determine the URL for a
 * given Prismic document.
 *
 * @type {prismic.ClientConfig["routes"]}
 */
const 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',
  },
]

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

  prismicNext.enableAutoPreviews({
    client,
    previewData: config.previewData,
    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
pages/[[...uid]].js
Copy
import * as prismicH from '@prismicio/helpers'
import { createClient } from '../prismicio'

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

  /*
   * `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 uid = params.uid[params.uid.length - 1]

  const page = await client.getByUID('page', uid)

  return {
    props: {
      slices: page.data.body,
    },
  }
}

// Define Paths
export async function getStaticPaths() {
  const client = createClient()

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

  return {
    paths: pages.map((page) => prismicH.asLink(page)),
    fallback: true,
  }
}
Defined folder structure
pages/[lang]/[section]/[category]/[uid].js
Copy
import * as prismicH from '@prismicio/helpers'
import { createClient } from '../prismicio'

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

  const page = await client.getByUID('page', params.uid)

  return {
    props: {
      slices: page.data.body,
    },
  }
}

// Define Paths
export async function getStaticPaths() {
  const client = createClient()

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

  return {
    paths: pages.map((page) => prismicH.asLink(page)),
    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.