In Next.js, it's best to think of getStaticProps
as a way to create static web pages. Not necessarily pages that are prebuilt during the initial build.
So if you use incremental static regeneration, you can use getStaticProps
on the blog post pages.
What is "incremental static regeneration"?
Essentially, you use getStaticProps
to tell Next.js to generate a static page (or set of pages) that may change over time. So you can have page with all your blog posts and tell Next.js that it may update every day.
// posts.js
export const getStaticProps = async () => {
const blogPosts = await getAllBlogPosts()
return {
props: { blogPosts },
revalidate: 60 * 60 * 24 // 1 day in seconds
}
}
This way, Next.js will create a static version of the blog posts that expires after 1 day. So the next, day, it will regenerate a new static version of the page. That way, if you add a new blog post, it will show up the day it's published.
I'd recommend checking out the docs on this topic as it has a lot more detail: https://nextjs.org/docs/basic-features/data-fetching#incremental-static-regeneration
What about individual blog posts?
Next.js can also let you add new blog post pages without having to rebuild the entire site. To do this, you need to create an individual blog post page with a dynamic route.
First, create a page in posts/[slug].js
. This is a dynamic route where you can connect a slug to an individual blog post.
Then, add the getStaticPaths function. Make sure to set fallback to either true
or blocking
. The docs fleshes out the difference in more detail.
export const getStaticPaths = async () => {
return {
paths: []
fallback: 'blocking'
}
}
This tells Next.js that it can expect anything as a slug. That way, new blog posts can be added in the future without rebuilding the entire site.
Then, add your getStaticProps
function to give the page it's details.
export const getStaticProps = async (context) => {
const post = await getPostBySlug(context.params.slug)
if(!post) return { redirect: '/posts', permanent: false } // redirect to main blog posts page if post doesn't exist, or any other page you want
return {
props: { post }
}
}