Skip to content

Pre-Rendering Routes With Multiple Parameters in Next.js


When you want Next.js to generate pages of a dynamic route, you must give it all the possible paths of that route ahead of time.

To achieve that, you have to use the getStaticPaths function in your [param].tsx page file.

For example, to generate a page each category in a blog, you would do something like this:

// src/pages/category/[slug].ts

export async function getStaticPaths() {
  return {
    paths: [
      { params: { slug: 'react' } },
      { params: { slug: 'typescript' } },
    fallback: false,

Doing that is straightforward for a page with a single parameter. But what if a category has many posts that are split up in multiple pages?

To fit that need, you have to move the slug to a folder and place a [page].ts file inside — category/[slug]/[page].ts.

To create all pages for such nested route, you need to provide every possible path combination in the paths array. If a category contains many pages, then you need to have an entry for each page with every slug.

It is very helpful to imagine what the final structure should be.

  { params: { slug: 'category', page: '1' } },
  { params: { slug: 'otherCategory', page: '1' } },
  { params: { slug: 'otherCategory', page: '2' } },
  { params: { slug: 'yetAnotherCategory', page: '1' } },

After understanding what you need to achieve, it’s a matter of modifying your data to fit the structure.

 function getStaticPaths() {
  const slugsWithPageAmount = getSlugsWithPageAmount(); // Your custom function

  // TypeScript helps to specify the required data structure
  const paths: { params: { slug: string; page: string } }[] = [];

  for (let item of slugsWithPageAmount) {
    for (let page = 1; page <= item.pageAmount; page++) {
        params: {
          slug: item.slug,
          page: page.toString(),

  return {
    fallback: false,

For every slug, you need to create objects that contain each individual page number and that slug.

Notice that you need to convert the page to string, because paths must be strings.

The key takeaway is to pass the paths array every possible combination of the route parameters.

It is helpful to hardcode the data first to see how the final structure should look like.