Next.js Image component error src missing though I am providing the src prop

Viewed 6132

I am providing the src prop to the UserCard but then also I am getting the error below.

Error

Unhandled Runtime Error
Error: Image is missing required "src" property. Make sure you pass "src" in props to the `next/image` component. Received: {"width":50,"height":50}

The Code in different Files is below

In UserCard.js


import Avatar from './Avatar';
import Link from 'next/link';

export default function UserCard({ user, border, onClick }) {
    function handleCloseAll() {
        if (onClick) onClick();
    }
    return (
        <div
            className={`d-flex p-2 align-items-center justify-content-between w-100 ${border}`}>
            <div onClick={handleCloseAll}>
                <Link href={`/profile/${user._id}`}>
                    <a className='d-flex align-items-center text-decoration-none'>
                        <Avatar.Big src={user.avatar} />
                        <div className='ml-1' style={{ transform: 'translateY(-2px)' }}>
                            <span className='d-block'>{user.username}</span>
                            <span
                                style={{
                                    opacity: 0.7
                                }}>
                                {user.fullname}
                            </span>
                        </div>
                    </a>
                </Link>
            </div>
        </div>
    );
}

in Avatar/Big.js

import Image from 'next/image';
import { useSelector } from 'react-redux';
import styles from '../../../styles/avatar.module.css';
export default function Big({ src }) {
    const { darkMode } = useSelector(state => state);
    return (
        <div
            style={{
                filter: darkMode ? 'invert(1) hue-rotate(180deg)' : 'invert(0)'
            }}>
            <Image
                className={styles.avatar}
                width={50}
                height={50}
                src={src}
                alt='Avatar'
            />
        </div>
    );
}

in Avatar/index.js

import Super from './Super';
import Big from './Big';
import Medium from './Medium';
import Small from './Small';
const Avatar = {
    Super: Super,
    Big: Big,
    Medium: Medium,
    Small: Small
};

export default Avatar;

Effort

If I am using the native <img /> it is working as expected


import Avatar from './Avatar';
import Link from 'next/link';

export default function UserCard({ user, border, onClick }) {
    function handleCloseAll() {
        if (onClick) onClick();
    }
    return (
        <div
            className={`d-flex p-2 align-items-center justify-content-between w-100 ${border}`}>
            <div onClick={handleCloseAll}>
                <Link href={`/profile/${user._id}`}>
                    <a className='d-flex align-items-center text-decoration-none'>
                        <img src={user.avatar} />
                        <div className='ml-1' style={{ transform: 'translateY(-2px)' }}>
                            <span className='d-block'>{user.username}</span>
                            <span
                                style={{
                                    opacity: 0.7
                                }}>
                                {user.fullname}
                            </span>
                        </div>
                    </a>
                </Link>
            </div>
        </div>
    );
}

More Details

I am using Nextjs version 11.0.1

Github Repository Link for further insights :- https://github.com/KUSHAD/dogeshot

3 Answers

In Big.js try

{ src && (
    <Image 
        className={styles.avatar}
        width={50}
        height={50}
        src={src}
        alt='Avatar'
    />
)}

This only outputs the image if src has a value.

It is not how the error should be handled. If image src does not exist you should at least show a default value. When you get images from API calls, sometimes images might be corrupted or link does not exist any more.

Next.js Image component documentation does not mention but the Image component has onError prop. In your component

export default function Big(props) {
  const { src } = props;
 // initially use the passed url as imgSrc
  const [imgSrc, setImgSrc] = useState(src);
  const { darkMode } = useSelector((state) => state);
  
  // If Image component throws an error, set default 
  const handleOnError = () => {
    setImgSrc("/static/yourImage.jpg");
  };
  return (
    <div
      style={{
        filter: darkMode ? "invert(1) hue-rotate(180deg)" : "invert(0)",
      }}
    >
      <Image
        className={styles.avatar}
        width={50}
        height={50}
        src={imgSrc}
        alt="Avatar"
        // if src does not exist this function will be triggered
        onError={handleOnError}
      />
    </div>
  );
}

in Avatar/Big.js you should use initial value for src. in first render the value is null add this code:

import Image from 'next/image';
import {useState,useEffect} from 'react';
import { useSelector } from 'react-redux';
import styles from '../../../styles/avatar.module.css';
export default function Big({ src }) {
const [image,setImage] = useState("/defaultImage")
useEffect(()=>{
if(src){
setImage(src)
}
},[src])
    const { darkMode } = useSelector(state => state);
    return (
        <div
            style={{
                filter: darkMode ? 'invert(1) hue-rotate(180deg)' : 'invert(0)'
            }}>
            <Image
                className={styles.avatar}
                width={50}
                height={50}
                src={image}
                alt='Avatar'
            />
        </div>
    );
}
Related