Here is how I implement a placeholder for loading images in my code snippet
'using client'
import { useCallback, useMemo, useState } from 'react';
import Image, { ImageProps } from 'next/image';
import loadingPlaceholder from '@/assets/images/loading-placeholder.svg';
import errorPlaceholder from '@/assets/images/error-placeholder.svg';
const ImageWithPlaceHolder = ({ src, alt, ...otherProps }: ImageProps) => {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
const startLoading = useCallback(() => setLoading(true), []);
const completeLoading = useCallback(() => setLoading(false), []);
const errorHandler = useCallback(() => setError(true), []);
const internalSrc = useMemo(
() => (error ? errorPlaceholder : loading ? loadingPlaceholder : src),
[error, loading, src],
);
return (
<Image
src={internalSrc}
alt={alt}
{...otherProps}
onError={errorHandler}
onLoadStart={startLoading}
onLoadingComplete={completeLoading}
/>
);
};
export default ImageWithPlaceHolder;