'TypeError: Cannot read property 'title' of undefined NextJS
I've been trying to build this blog app, Before is fine and in the dev environment is also fine. But, as soon as i try to build it for production it caught in this error.
Error occurred prerendering page "/blogs/[slug]". Read more: https://nextjs.org/docs/messages/prerender-error TypeError: Cannot read property 'title' of undefined
I am confused because this app had been build before and nothing is wrong. This is the culprit:
import Head from "next/head";
import "bootstrap/dist/css/bootstrap.min.css";
import ReactMarkdown from "react-markdown";
import moment from "moment";
const Post = ({ posts }) => {
return (
<>
<Head>
<title>{posts && posts.title}</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
></meta>
</Head>
<div className="container" style={{ marginTop: "3.85rem" }}>
<div className="row">
<h1>{posts.title}</h1>
</div>
<div className="row d-flex justify-content-end">
<p style={{ textAlign: "right" }}>
{moment(posts.dateTime).format("dddd, Do MMMM YYYY, hh:mm:ss a")}
</p>
</div>
<br />
<div className="row d-flex justify-content-center">
<img
className="postThumbNail"
src={posts.thumbnail.url}
alt={posts.thumbnail.url}
/>
</div>
<br />
<ReactMarkdown>{posts.body}</ReactMarkdown>
</div>
</>
);
};
export async function getStaticProps({ params: { slug } }) {
const res = await fetch(
`https://someapi.com/blogs?slug=${slug}`
);
const blogPost = await res.json();
return {
props: {
posts: blogPost[0],
},
revalidate: 600,
};
}
export async function getStaticPaths() {
// Get Post From Strapi
const res = await fetch(
"https://someapi.com/blogs"
);
const post = await res.json();
// Retrun Enrich Content
return {
paths: post.map((posts) => ({
params: { slug: String(posts.slug) },
})),
fallback: true,
};
}
export default Post;
Solution 1:[1]
Solution 1 You need to check if attribute exists first
<h1>{posts?.title}</h1>
Solution 2
or object is not null return null
until data loads
if(!posts) return null
return <div> ...Code </div>
Solution 2:[2]
<Head>
<title>{posts && posts.title}</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
></meta>
</Head>
<div className="container" style={{ marginTop: "3.85rem" }}>
<div className="row">
<h1>{posts && posts.title}</h1> // You've just forgot that if posts exist condition
</div>
<div className="row d-flex justify-content-end">
<p style={{ textAlign: "right" }}>
{moment(posts.dateTime).format("dddd, Do MMMM YYYY, hh:mm:ss a")}
</p>
</div>
<br />
<div className="row d-flex justify-content-center">
<img
className="postThumbNail"
src={posts.thumbnail.url}
alt={posts.thumbnail.url}
/>
</div>
<br />
<ReactMarkdown>{posts && posts.body}</ReactMarkdown>
</div>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | kyun |