How to use multiple nested dynamic routes with getStaticPaths?

Viewed 7215

This is my page tree

├── _app.tsx
├── _document.tsx
├── index.tsx
└── [type]
    └── [slug].tsx

and this is the getStaticPaths for the [slug] page:

export const getStaticPaths: GetStaticPaths = async () => {
  const posts = getAllPosts(["slug"]);

  return {
    paths: posts.map((posts) => {
      return {
        params: {
          type: posts.mainTag,
          slug: posts.slug,
        },
      };
    }),
    fallback: false,
  };
};

so the a page would look like this for example http://localhost:3000/programming/some-slug

when i go to a certain post, i get this error:

A required parameter (type) was not provided as a string in getStaticPaths for /[type]/[slug]

i just don't know how i would go about providing the type parameter to the router.

1 Answers

The sample code above seems correct, so I would try two things:

1) I don't see an await prefix when calling getAllPosts(["slug"]) - this would mean you are returning before you have the data.

Unless that is be design, change to:

const posts = await getAllPosts(["slug"]);

2) There may be a data issue and you missing expected properties. I would suggest you check getStaticPaths by replacing with a simple array:

const Test = (props) => {
    return (
       <>
           {props.slug}
       </>
    );
};

export async function getStaticProps({params}) {
    return {
        props: params
    }
}

export async function getStaticPaths() {
    const posts = [
        {
            mainTag: 'programming',
            slug: 'hello-world'
        },
        {
            mainTag: 'programming',
            slug: 'nextjs-101'
        },
    ];

    return {
        paths: posts.map((posts) => {
            return {
                params: {
                    type: posts.mainTag,
                    slug: posts.slug,
                },
            };
        }),
        fallback: false,
    };
}

export default Test;
Related