I'm struggling to incorporate a dynamic table of contents into my blog page on next.js. The code functions perfectly on my local server, but upon deploying it to Vercel, I encounter the following error:
TypeError: Cannot read properties of undefined (reading 'content')
at BlogPost (/vercel/path0/.next/server/pages/posts/[slug].js:111:23)
at Jc (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:64:191)
at Mc (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:66:253)
at Z (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:71:89)
at Nc (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:73:98)
at Mc (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:67:131)
at Z (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:71:89)
at Mc (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:70:13)
at Z (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:71:89)
at Nc (/vercel/path0/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js:73:98)
Upon investigation, I discovered that the build failure is triggered by the .processSync command on line 85 (as indicated in my comment). Unfortunately, resolving this issue has been beyond my capability... Any insights or assistance as to why this occurs would be greatly appreciated.
Here's the complete source code: (I've omitted the grahpcms route when setting up the GraphQLClient for security reasons, so that's not the cause of failure here.)
import { GraphQLClient, gql } from "graphql-request";
import { useRouter } from "next/router";
import { unified } from "unified";
import rehypeParse from "rehype-parse/lib";
import rehypeStringify from "rehype-stringify/lib";
import { visit } from "unist-util-visit";
import parameterize from "parameterize";
const graphcms = new GraphQLClient();
const QUERY = gql`
query Post($slug: String!) {
post(where: { slug: $slug }) {
title
id
content {
html
}
datePublish
coverPhoto {
url
}
datePublish
}
}
`;
const SLUGLIST = gql`
{
posts {
slug
}
}
`;
export async function getStaticPaths() {
const { posts } = await graphcms.request(SLUGLIST);
return {
paths: posts.map((post) => ({ params: { slug: post.slug } })),
fallback: true,
};
}
export async function getStaticProps({ params }) {
const slug = params.slug;
const data = await graphcms.request(QUERY, { slug });
const post = data.post;
return {
props: {
post,
},
};
}
export default function BlogPost({ post }) {
const router = useRouter();
var toc = [];
//Forms the HTML String into a tree that we can add logic too
//Then forms that tree back into html string
const newContent = unified()
.use(rehypeParse, {
fragment: true,
})
.use(() => {
return (tree) => {
visit(tree, "element", (node) => {
if (node.tagName === "h2") {
const id = parameterize(node.children[0].value);
node.properties.id = id;
toc.push({
id: node.properties.id,
title: node.children[0].value,
});
console.log("id", id);
}
});
};
})
.use(rehypeStringify)
//THIS IS WHERE THE DELPLOYMENT FAILS
.processSync(post.content.html)
.toString();
if (router.isFallback) {
return <h2>Loading</h2>;
}
return (
<div>
<header>
<h1>{post.title}</h1>
<img
src={post.coverPhoto.url}
width="100%"
style={{ borderRadius: "1rem" }}></img>
<span>Published: {post.datePublish}</span>
</header>
<main>
<div>
{toc.map(({ id, title }) => {
return (
<li style={{ listStyle: "none" }} key={id}>
<a style={{ fontSize: "1.1rem" }} href={`#${id}`}>
<b> {title}</b>
</a>
</li>
);
})}
</div>
<div
className="blogpost"
dangerouslySetInnerHTML={{ __html: newContent }}
/>
</main>
</div>
);
}
Your assistance will be highly appreciated!