I'm making e-commerce Next.js static app.
For my products pages I'm using incremental static generation (I'll call it ISG further) with fallback: true
and simple useRouter
for showing loading component (like spinner or something else, it doesn’t matter). ISG is very useful function for static sites with frequent updating data (like adding comments, new products and so on), but if I don't have product path (for example /products/nike-pants-12345
) the page will return "infinity loading" and error.
The error is below.
If we take a look in console we can see something like: TypeError: Cannot read property '_id' of null
. It means that app didn't find product with requested _id (it could be name, slug and so on).
So, the question is how I can avoid this case and should this one be avoided at all?
export async function getStaticPaths() {
await dbConnect()
const products = await ProductModel.find({})
const paths = products.map((doc) => {
const product = doc.toObject()
return {
params: { id: product._id.toString() }
}
})
/* fallback: true means that the missing pages
will not 404, and instead can render a fallback */
return { paths, fallback: true }
}
export async function getStaticProps({ params }) {
await dbConnect()
const product = await ProductModel.findById(params.id).lean()
product._id = product._id.toString()
// revalidate set the time (in sec) of re-generate page (it imitate SSR)
return { props: { product }, revalidate: 30 }
}
You could trigger a 404 page by adding a check for product
and return notFound: true
if no product was found in getStaticProps
.
export async function getStaticProps({ params }) {
await dbConnect()
const product = await ProductModel.findById(params.id).lean()
if (!product) {
return {
notFound: true
}
}
product._id = product._id.toString()
// revalidate set the time (in sec) of re-generate page (it imitate SSR)
return { props: { product }, revalidate: 30 }
}