Search code examples
reactjsnext.jsnested-routesnextjs-dynamic-routing

Error with getStaticPaths() and getStaticProps() with nested routes in NextJS 14


I am making a blog with two level nested routes: example.com/blogs/[chapterID]/[postID] The static posts saved in local folder (outside the app folder) as markdown files.

enter image description here

The urls are stored in the blogs.json.


[
  {
    "header": "Header for Category1",
    "id": "category1",
    "topicList": [
      {
        "title": "post1 title",
        "url": "cat1-post1.md"
      },
      {
        "title": "post2 title",
        "url": "cat1-post2.md"
      },
      {
        "title": "post3 title",
        "url": "cat1-post3.md"
      }
    ]
  },
  {
    "header": "Header for Category 2",
    "id": "category2",
    "topicList": [
      {
        "title": "Cat2 Post1 title",
        "url": "cat2-post1.md"
      },
      {
        "title": "Cat2 Post2 title ",
        "url": "cat2-post2.md"
      },
      {
        "title": "Cat2 Post3 title ",
        "url": "cat2-post3.md"
      }
    ]
  },
  {
    "header": "Header for Category 3",
    "id": "category3",
    "topicList": [
      {
        "title": "Cat3 Post1 title",
        "url": "cat3-post1.md"
      },
      {
        "title": "Cat3 Post2 title ",
        "url": "cat3-post1.md"
      }
    ]
  }
]


The page works but I am having hardtime to generate static paths and props.

My page.tsx inside [postID] is-


    import React from 'react'
    
    import fs from "fs"
    
    import Markdown from "react-markdown"
    import rehypeKatex from "rehype-katex"
    import remarkMath from "remark-math"
    import rehypeRaw from "rehype-raw"
    import matter from "gray-matter"
    import 'katex/dist/katex.min.css'
    
    import BlogMenu from '../../blogs.json'
    import path from "path"
    
    
    
    const allPosts = BlogMenu.flatMap(({ header, id, topicList }) =>
      topicList.map((topics) => ({
    
        sectionName: header,
        sectionId: id,
        ...topics,
    
      })),
    );
    
    
    const folder = path.join(process.cwd(), 'src/BlogPages');// declare it outside of app folder
    
    const getPostContent = (chapterID:string, postID: string) => {
      
      const file = `${folder}/${chapterID}/${postID}.md`;
      const content = fs.readFileSync(file, "utf8");
      const matterResult = matter(content);
      return matterResult;
    };
    
    
    
    
    export async function getStaticPaths() {
    
      return {
        paths: allPosts.map((post) => ({
          params: {
            chapterID: post.sectionId,
            postID: post.url
          },
        })),
        fallback: false,
      };
    }
    export async function getStaticProps(chapterID:string, postID: string) {
      
      const postProps = getPostContent(chapterID, postID) // Retrieve data for given type/slug pair
    
      return {
        props: {
          data: postProps
        }
      }
    }
    
    
    
    const BlogPage = (props: any) => {
      const chapterID = props.params.chapterID
      const postID = props.params.postID;
      
      const post = getPostContent(chapterID, postID)
    
      return (
    
        <>
    
          <h1>{post.data.title}</h1>
          <hr className="my-6 border border-dashed bg-teal-600 h-0.5" />
          <article className="prose lg:prose-xl">
            <Markdown remarkPlugins={[remarkMath]} rehypePlugins={[rehypeKatex, rehypeRaw]}>
              {post.content}</Markdown>
          </article>
        </>
    
      )
    }
    
    export default BlogPage

When I run npm run build it shows the error-

> next build

   ▲ Next.js 14.0.4

 ✓ Creating an optimized production build    
 ✓ Compiled successfully
   Linting and checking validity of types  ...Failed to compile.

src/app/(routes)/blogs/[chapterID]/[postID]/page.tsx
Type error: Page "src/app/(routes)/blogs/[chapterID]/[postID]/page.tsx" does not match the required types of a Next.js Page.
  "getStaticPaths" is not a valid Page export field.

And for getStaticProps() I am getting the error-

File path:
  ./src/app/(routes)/blogs/[chapterID]/[postID]/page.tsx
 ⨯ ./src/app/(routes)/blogs/[chapterID]/[postID]/page.tsx
ReactServerComponentsError:

"getStaticProps" is not supported in app/. Read more: https://nextjs.org/docs/app/building-your-application/data-fetching

Any suggestion about solving the error will be appreciated. Thanks in advance.


Solution

  • After a lots of searching, it seems that since NextJS 13 they have introduced new app directory and calling getStaticProps() or getStaticPaths() inside the app will cause the error. This error can be solved by using generateStaticParams() instead.

    export async function generateStaticParams() {
      return allPosts.map((post) => ({
        chapterID: post.sectionId,
        postID: post.url
    
      }))
    }
    

    I have removed my getStaticProps() and getStaticPaths() functions and used the above code to generate static slug. Hope it will help someone. You will find more details about generateStaticParams() in this link.