Dynamic Routes

Implement getStaticProps

We need to fetch necessary data to render the post with the given id.

To do so, open lib/posts.js again and add this function. This will return the post data based on id:

export function getPostData(id) {
  const fullPath = path.join(postsDirectory, `${id}.md`)
  const fileContents = fs.readFileSync(fullPath, 'utf8')

  // Use gray-matter to parse the post metadata section
  const matterResult = matter(fileContents)

  // Combine the data with the id
  return {
    id,
    ...matterResult.data
  }
}

Finally, in pages/posts/[id].js, replace this line:

import { getAllPostIds } from '../../lib/posts'

…with this:

import { getAllPostIds, getPostData } from '../../lib/posts'

And create getStaticProps which calls this function:

export async function getStaticProps({ params }) {
  const postData = getPostData(params.id)
  return {
    props: {
      postData
    }
  }
}

Then update the Post component to use postData:

export default function Post({ postData }) {
  return (
    <Layout>
      {postData.title}
      <br />
      {postData.id}
      <br />
      {postData.date}
    </Layout>
  )
}

That’s it! Try visiting these pages:

You should be able to see the blog data for each page:

Great! We’ve successfully generated dynamic routes.

Something Wrong?

If you come across an error, make sure your files have the correct code:

If you’re still stuck, feel free to ask the community on GitHub Discussions. It’d be helpful if you could push your code to GitHub and link to it so others can take a look.

Summary

Again, here’s the graphical summary of what we’ve done:

We still haven’t displayed the blog markdown content. Let’s do this next.

Quick Review: How does params.id from getStaticProps({ params }) know the key is named id?