skip to Main Content

Click to view the error message

This is my componentsPromptCard.jsx code :-

"use client";

import { useState } from "react";
import Image from "next/image";
import { useSession } from "next-auth/react";
import { usePathname, useRouter } from "next/navigation";

const PromptCard = ({ post, handleEdit, handleDelete, handleTagClick }) => {
    const { data: session } = useSession();
    const pathName = usePathname();
    const router = useRouter();

    const [copied, setCopied] = useState("");

    const handleProfileClick = () => {
        console.log(post);

        if (post.creator._id === session?.user.id) return router.push("/profile");

        router.push(`/profile/${post.creator._id}?name=${post.creator.username}`);
    };

    const handleCopy = () => {
        setCopied(post.prompt);
        navigator.clipboard.writeText(post.prompt);
        setTimeout(() => setCopied(false), 3000);
    };

    return (
        <div className='prompt_card'>
            <div className='flex justify-between items-start gap-5'>
                <div
                    className='flex-1 flex justify-start items-center gap-3 cursor-pointer'
                    onClick={handleProfileClick}
                >
                    <Image
                        src={post.creator.image}
                        alt='user_image'
                        width={40}
                        height={40}
                        className='rounded-full object-contain'
                    />

                    <div className='flex flex-col'>
                        <h3 className='font-satoshi font-semibold text-gray-900'>
                            {post.creator.username}
                        </h3>
                        <p className='font-inter text-sm text-gray-500'>
                            {post.creator.email}
                        </p>
                    </div>
                </div>

                <div className='copy_btn' onClick={handleCopy}>
                    <Image
                        src={
                            copied === post.prompt
                                ? "/assets/icons/tick.svg"
                                : "/assets/icons/copy.svg"
                        }
                        alt={copied === post.prompt ? "tick_icon" : "copy_icon"}
                        width={12}
                        height={12}
                    />
                </div>
            </div>

            <p className='my-4 font-satoshi text-sm text-gray-700'>{post.prompt}</p>
            <p
                className='font-inter text-sm blue_gradient cursor-pointer'
                onClick={() => handleTagClick && handleTagClick(post.tag)}
            >
                {post.tag}
            </p>

            {session?.user.id === post.creator._id && pathName === "/profile" && (
                <div className='mt-5 flex-center gap-4 border-t border-gray-100 pt-3'>
                    <p
                        className='font-inter text-sm green_gradient cursor-pointer'
                        onClick={handleEdit}
                    >
                        Edit
                    </p>
                    <p
                        className='font-inter text-sm orange_gradient cursor-pointer'
                        onClick={handleDelete}
                    >
                        Delete
                    </p>
                </div>
            )}
        </div>
    );
};

export default PromptCard;

I tried updating my NextJS to the latest version, also checked all the environment variables and all seem to work perfectly. The code was working well and good but once I deployed it using Vercel, this error showed up.
I tried running in my localhost and the same error popped up. This wasn’t there before I deployed it to vercel.

Application error: a client-side exception has occurred (see the browser console for more information).

This error shows on the browser when I deployed it.

Here’s the website link : https://quasar-prompts.vercel.app/

Here’s the Github link : https://github.com/AnanteshG/Quasar

If anybody knows how to fix it let me know please. Thanks in Advance!

2

Answers


  1. post.creator might be null or undefined.

     <Image
      src={post.creator.image}
      alt='user_image'
      width={40}
      height={40}
      className='rounded-full object-contain'
     />
    

    Try this:

    <Image
     src={post.creator?.image}  
     alt='user_image'
     width={40}
     height={40}
     className='rounded-full object-contain'
    />
    
    Login or Signup to reply.
  2. Since your component renders data inside post.creator you can either add a null check or render the component only if the data is available.

    Add null check wherever post.creator is consumed as:

    post.creator?.username or give a fallback as post.creator.username ?? "John Doe"

    Or render only if post.creater has data, as:

    "use client";
    
    import { useState } from "react";
    import Image from "next/image";
    import { useSession } from "next-auth/react";
    import { usePathname, useRouter } from "next/navigation";
    
    const PromptCard = ({ post, handleEdit, handleDelete, handleTagClick }) => {
        const { data: session } = useSession();
        const pathName = usePathname();
        const router = useRouter();
    
        const [copied, setCopied] = useState("");
    
        const handleProfileClick = () => {
            console.log(post);
    
            if (post.creator._id === session?.user.id) return router.push("/profile");
    
            router.push(`/profile/${post.creator._id}?name=${post.creator.username}`);
        };
    
        const handleCopy = () => {
            setCopied(post.prompt);
            navigator.clipboard.writeText(post.prompt);
            setTimeout(() => setCopied(false), 3000);
        };
    
        if(!post.creator){
          return <div>Insufficient data!</div>
        }
    
        return (
            <div className='prompt_card'>
                <div className='flex justify-between items-start gap-5'>
                    <div
                        className='flex-1 flex justify-start items-center gap-3 cursor-pointer'
                        onClick={handleProfileClick}
                    >
                        <Image
                            src={post.creator.image}
                            alt='user_image'
                            width={40}
                            height={40}
                            className='rounded-full object-contain'
                        />
    
                        <div className='flex flex-col'>
                            <h3 className='font-satoshi font-semibold text-gray-900'>
                                {post.creator.username}
                            </h3>
                            <p className='font-inter text-sm text-gray-500'>
                                {post.creator.email}
                            </p>
                        </div>
                    </div>
    
                    <div className='copy_btn' onClick={handleCopy}>
                        <Image
                            src={
                                copied === post.prompt
                                    ? "/assets/icons/tick.svg"
                                    : "/assets/icons/copy.svg"
                            }
                            alt={copied === post.prompt ? "tick_icon" : "copy_icon"}
                            width={12}
                            height={12}
                        />
                    </div>
                </div>
    
                <p className='my-4 font-satoshi text-sm text-gray-700'>{post.prompt}</p>
                <p
                    className='font-inter text-sm blue_gradient cursor-pointer'
                    onClick={() => handleTagClick && handleTagClick(post.tag)}
                >
                    {post.tag}
                </p>
    
                {session?.user.id === post.creator._id && pathName === "/profile" && (
                    <div className='mt-5 flex-center gap-4 border-t border-gray-100 pt-3'>
                        <p
                            className='font-inter text-sm green_gradient cursor-pointer'
                            onClick={handleEdit}
                        >
                            Edit
                        </p>
                        <p
                            className='font-inter text-sm orange_gradient cursor-pointer'
                            onClick={handleDelete}
                        >
                            Delete
                        </p>
                    </div>
                )}
            </div>
        );
    };
    
    export default PromptCard;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search