Table of contents not working on Vercel, yet functions properly on localhost

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!

Answer №1

To handle undefined props, you can utilize the optional chaining operator like so:

post?.content?.html

Another step to consider is running the project on your local machine instead of relying on Vercel for building and catching any additional errors.

By using an if statement, you can manage undefined props effectively - just remember to position it before the main return statement and after all hooks in your code.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble developing a custom jQuery tool for textareas

I am currently attempting to customize this script that mimics the Word 2007 minibar within a textarea. My approach involves encapsulating it in a plugin, but I am encountering an issue where it does not function properly with multiple textareas. If you w ...

Troubleshooting problems with AJAX function in the .each() loop

My webpage showcases a grid layout with 16 blocks arranged in 4 columns and 4 rows. As you scroll to the bottom of the page, an AJAX function dynamically loads another set of 16 blocks each time. To enhance user experience, I wanted to implement a smooth ...

How can I smoothly navigate to the top of a page using AngularJS?

After receiving an ajax call response using angularjs, I am looking to automatically scroll to the top of the page. The purpose is to bring focus to alert messages displayed at the top of the page upon receiving the ajax response. Appreciate any guidance ...

Is there a way to dynamically alter the fill color of an SVG component using props along with tailwindcss styling?

Having a bit of trouble cracking this code puzzle. I've got a logo inside a component, but can't seem to pass the className fill options correctly. This is all happening in a NextJS environment with NextUI and tailwind css. const UserLogo = (prop ...

Potential causes for Chrome to send duplicate requests

In my nginx server logs, I have the following entries (IPs and paths altered for illustration purposes): 101.101.101.101 - - [15/Apr/2020:14:46:03 +0000] "GET /item/download-file/ready/5e971e290107e HTTP/2.0" 200 142940 "https://example.com/referer" "Mo ...

Best practices for organizing and storing a todo list in ReactJS using local storage

import React, { useState, useEffect } from 'react'; const TodoList = () => { const [tasks, setTasks] = useState(JSON.parse(localStorage.getItem('tasks')) || []); const [newTask, setNewTask] = useState(''); con ...

Setting no border color for the phone input when utilizing react-phone-number-input

Currently, I am utilizing the react-phone-number-input library for handling phone number input. Below is the code snippet for the phone number field: <PhoneInput defaultCountry={"CA"} placeholder={"Phone"} value={phone} ...

Develop a distinctive JavaScript solution that enables an image to appear in fullscreen upon loading the page, and then smoothly fade away after precisely

I have been trying to incorporate a feature on my Shopify frontage website where our logo appears fullscreen and then fades away or disappears after a few seconds, allowing people to access the rest of the website. However, I am facing difficulty in making ...

The Next.js image feature encounters a 500 error when in a production environment

I recently deployed my Next.js app on GAE and encountered an issue where none of the images located in the public folder were properly served. Every time I tried to access them, a 500 error occurred, accompanied by this specific error message found upon re ...

Hide the background when the modal appears

I have successfully implemented a jQuery CustomBox modal on my website. However, I am facing an issue with hiding the content div behind the modal once it pops up. My goal is to make the content div reappear after the modal has been closed. You can view a ...

Using the $inc operator in mongoose to avoid decrementing a value below zero

My code successfully deducts credit from a user using $inc in Mongoose, but the concern is that the value can become negative, which is not ideal. Is there any way to prevent this? module.exports.deduct_credit = function(subscriber_email,callback){ Us ...

Using Three JS: Import an OBJ file, move it to the center of the scene, and rotate around it

I am trying to figure out how to load an OBJ file and translate its coordinates to the world origin (0,0,0) in order to make orbit controls function smoothly without using Pivot points. My goal is to automatically translate random OBJ objects with differe ...

Tips for implementing conditional styling (using else if) in a react component

Currently, while iterating through a list of header names, I am attempting to change the CSS style of a react component based on three different conditions. I have managed to make it work for one condition, but I am facing challenges when trying to impleme ...

Is Python a suitable programming language for developing applications on a Raspberry Pi device?

I'm diving into the coding world for the first time and I have a project in mind - controlling my RC car with my smartphone using a Raspberry Pi 3. Research suggests that I should use Node.JS and JavaScript to create the app, but I'm wondering if ...

How to modify a single entry in a MongoDB database with the help of Node.js and

How do I update a specific record by _id in a MongoDB collection? A recent UPDATE: After making some changes to the code, I now encounter a 500 internal server error. Any suggestions on resolving this issue would be greatly appreciated. "_id ...

Utilizing Next.js to dynamically update data within a div element upon

I have a table set up to display data and I want to transfer the row data into a div when the user clicks on a table row: Currently, I can successfully get the data onclick: const handleClick = (rowData) => { console.log(rowData); } However, I am ...

What are the differences between using embedded documents and references in a mongoose design model?

I am currently in the process of developing a discussion forum using Node.js and mongoose. The structure I have in mind involves users being able to participate in multiple forums, with each forum containing multiple comments. Additionally, users should ha ...

Invoking a Components function from a Service in Angular may lead to a potential cyclic dependency issue

I am facing a challenge where I need to call a function from my filterComponent(component) within my engagementService(service). The function in my filterComponent accesses an array that is located within the engagementService. It uses the data from this ...

How does the question mark symbol (?) behave when utilizing it in response? Specifically in relation to data, the API, and the fetch API

Have you encountered the curious sequence of symbols in this context? data?.name Could you explain the significance of the question mark (?) between 'data' and the period? ...

Error caught: The `onClick` listener was anticipated to be a function, but instead, it was found to be of type `object` in

While attempting to delete a customer entry with a specific id, I encountered an issue in my customers.js file. Despite adding a delete function, the entry was not being removed successfully. The console displayed the following error: caught Error: Expec ...