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.
Use 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.
To create consistent website paths, define your paths in three places:
- In your website folder structure. For example the file, pages/about.js will return a page for the URL /about. You can learn more about Next.js routes in the Next.js documentation.
- In the getStaticPaths() function for dynamic routes. You’ll need a getStaticPaths() function to define every page that Next.js will render for a given dynamic route. For example, for /pages/[uid].js, getStaticPaths() should specify all matching pages, like /about, /pricing, and /contact.
- In the routes option of your Prismic client configuration. This populates URLs for internal links and documents in Prismic API responses.
Next, we’ll explain how to implement these paths.
If you have a fixed page, like pages/about.js, you don’t need getStaticPaths(). Next.js already knows the route and the content for the route. However, you still need to define the route in your Prismic routes option, to enable internal linking.
This is a route in the routes option for the About page:
const routes = [
{
type: "page",
uid: "about",
path: "/about",
},
]
In Next.js’s filesystem-based routing, dynamic path segments are defined inside square brackets: pages/[uid].js. This route handles any URL with a single path segment, such as /apples or /carrots. The square brackets around [uid] act as a wildcard.
Next.js’s static generation will pre-render all the pages in your website to optimize page speed. To do so, Next.js must know what pages to render. getStaticPaths() tells Next.js what pages to render for a dynamic route, such as pages/[uid].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.
Here’s an example:
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: { page },
}
}
// 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,
}
}
Here, getStaticPaths() tells Next.js to render a page for every page document from Prismic. In the setup step, you defined a Route Resolver (the routes option). Next.js will generate a route for every document specified with your Route Resolver.
Here is the routes option for the above example:
const routes = [
{
type: "page",
path: "/:uid",
},
]
Next.js and Prismic both support nested paths. In Next.js, this is accomplished with filesystem-based routing. In Prismic, this is accomplished with the Route Resolver.
For example, you could have the file pages/[category]/[uid].js, which would return a file for the /*/* URL. That might render a page for /clothing/t-shirt or /dogs/doberman. Here’s how that looks in Next.js:
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,
}
}
Here is the routes option for the above example:
const routes = [
{
type: 'page',
resolvers: {
category: 'category',
},
path: '/:category/:uid',
},
]
Beyond using directories, Next.js also has a catch-all routes option, which looks like pages/[[...uid]].js. This would render a page for /*, /*/*, /*/*/*, etc. So, you could render a page for both /dogs/doberman and /poodle. Here’s how that looks in Next.js:
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,
}
}
Prismic’s Route Resolver allows for optional segments. The following routes option will conditionally render the :category segment only if it is present, otherwise omitting it:
const routes = [
{
type: 'page',
resolvers: {
category: 'category',
},
path: '/:category?/:uid',
},
]
- Your routes option should reflect the folder structure of your Next.js project.
- Next.js and Prismic work together to offer advanced routing with conditional segments, internationalization, and nested routes.
- When you have the routes option implemented, getStaticPaths() should look almost the same for every page file.
Was this article helpful?
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.