admin管理员组文章数量:1317565
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: 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(
`=${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(
";
);
const post = await res.json();
// Retrun Enrich Content
return {
paths: post.map((posts) => ({
params: { slug: String(posts.slug) },
})),
fallback: true,
};
}
export default Post;
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/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./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./blogs"
);
const post = await res.json();
// Retrun Enrich Content
return {
paths: post.map((posts) => ({
params: { slug: String(posts.slug) },
})),
fallback: true,
};
}
export default Post;
Share
Improve this question
asked Sep 27, 2021 at 5:24
KotjengOrenKotjengOren
791 silver badge8 bronze badges
2
-
2
You checked if posts exists here:
<title>{posts && posts.title}</title>
, but forgot to do it here:<h1>{posts.title}</h1>
– Nicholas Tower Commented Sep 27, 2021 at 5:25 - @NicholasTower Yep Sure, But now the problem is goes to post.dateTime, I mean the conditional did help but shall I do that for all? Is there any more graceful way of solving this? – KotjengOren Commented Sep 27, 2021 at 5:31
3 Answers
Reset to default 3Solution 1 You need to check if attribute exists first with optional chaining :
<h1>{posts?.title}</h1>
Solution 2
or object is not null return null
until data loads
if(!posts) return null
return <div> ...Code </div>
The issue occurs because you're using fallback: true
in getStaticPaths
, and you're not handling the fallback page which gets served by Next.js before getStaticProps
finishes running. At that point the props passed to the page ponent will be empty.
In the “fallback” version of a page:
- The page’s props will be empty.
- Using the router, you can detect if the fallback is being rendered,
router.isFallback
will betrue
.— Next.js, Fallback Pages documentation
#1 Handle fallback page with router.isFallback
You can properly handle the fallback version of the page using router.isFallback
.
const Post = ({ posts }) => {
const router = useRouter()
// Display loading until `getStaticProps()` finishes running, and populates the props.
if (router.isFallback) {
return <div>Loading...</div>
}
return (
<h1>{posts.title}</h1>
);
};
#2 Use fallback: 'blocking'
instead
As an alternative, if you don't really need the fallback functionality, you can change the fallback value in getStaticPaths
to fallback: 'blocking'
. This will still generate new pages like fallback: true
, but will wait until getStaticProps
has ran before rendering the page.
export async function getStaticPaths() {
const res = await fetch("https://someapi./blogs");
const post = await res.json();
return {
paths: post.map((posts) => ({
params: { slug: String(posts.slug) }
})),
fallback: 'blocking'
};
}
<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>
本文标签: javascriptTypeError Cannot read property 39title39 of undefined NextJSStack Overflow
版权声明:本文标题:javascript - TypeError: Cannot read property 'title' of undefined NextJS - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742021470a2414756.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论