Hyunseok
Dev

Nextjs에서 전역으로 image fallback을 설정해보자

2025-03-01

h150

뜬금 없지만 9월 9일을 .. 기다린다..

발단

뭐 별거 있겠는가 ? 오랜만에 블로그를 돌면서 부족한점들을 하나하나 뜯어 고치는 도중에 눈에 들어온 그것 ..

h100 아이고 두야

여하튼 뭐 .. 이걸 수정해야한다.

방법 1

인터넷에 조금씩 찾다보니 다들 말하는 방법으로는
Image컴포넌트를 씌운 wrapper image 컴포넌트를 작성하는 것이다.

typescript'use client'
import { FC, ImgHTMLAttributes, useEffect } from 'react'
import Image from 'next/image'
import { useState } from 'react'
 
type FallbackImageProps = ImgHTMLAttributes<HTMLImageElement>
export const FallbackImage: FC<FallbackImageProps> = ({ src, width, height, alt, ...props }) => {
    const [imgSrc, setImgSrc] = useState(src)
 
    useEffect(() => {
        setImgSrc(src)
    }, [src])
 
    return (
        <Image
            alt={alt ?? 'Image'}
            src={imgSrc ? imgSrc : '/images/fallback.png'}
            onError={() => {
                setImgSrc('/images/fallback.png')
            }}
            {...props}
        />
    )
}

근데 인터넷에 있는 방식으로하면 재미가 없지 않은가 ? 이미지태그가 여러번 박히는 페이지라고 가정하고 이상태로
휴먼 에러를 가정한다면..

그냥 페이지에서 hook을 하나 돌리게 나을 것이다.
그래서 나온게 다음 방법.

방법 2 (실제 사용)

typescript'use client'
 
import { useEffect } from 'react'
import fallback from './seyana.jpg'
 
export const ImageFallbackSetter = () => {
    useEffect(() => {
        const images = document.querySelectorAll('img')
        images.forEach((image) => {
            image.onerror = () => {
                image.srcset = fallback.src
                image.src = fallback.src
                image.onerror = null
                console.log('replaced')
            }
        })
    }, [])
    return null
}
 

페이지 전체의 error를 싸그리 fallback으로 바꾸는 아주 혁명적인 .. 그런 방법을 사용해주자

방법 1의 경우 생성되는 각 이미지마다 useState를 돌려서 쓸모없는 자원을 낭비하는 것 같기도하고 (미쳐버린 최적화 마인드)
여러모로 .. 코드가 안이쁘다 사실 이게 본심

마치면서

fallback처리 잘 해두자. 생각해보니 저번에 서버날라간 사건도 있었고 .. 지금은 아니지만 image server가 박살나는 경우에는
엑박 말고 fallback하나 띄워주면 또 이쁘게 나오지 않겠는가 ?

해피한 개발 이어나가자

개발NextjsFallback
Comments()