Skip to content

[트러블 슈팅] 모바일 SVG파일 깨짐

jogunhee edited this page May 26, 2025 · 2 revisions

투표 카드에서 내용이 긴 경우 y축 스크롤이 생기면서, 위 아래 미세 잘림 문제(5/26)

🐞 에러 내용

  • 모바일 환경에서 svg파일을 경로를 통해 <img> 태그에 사용할 경우, 일부 svg의 이미지가 깨지는 문제

🔍 원인 분석

  • 모바일 환경에서 svg를 img태그에 사용하면 파일의 레스터화(비트맵 이미지로 변환) 과정에서 원본 svg가 손상되는 경우가 발생한다. 그로인해, img가 정상적으로 보여지지 않음

✅ 해결 방법

  1. svg를 원본 파일 그대로 사용한다.
  2. <object> 태그를 이용한 원본 파일 렌더링

SVGComponent 렌더링을 사용했다. svg원본 파일을 이용하는 방법중 하나로 SVGComponent를 사용했다.

import * as React from 'react'
import { cn } from '@/lib/utils'

type SVGIcon = React.FC<React.SVGProps<SVGSVGElement>>

interface IconProps extends React.ImgHTMLAttributes<HTMLImageElement> {
  src?: string
  component?: SVGIcon
  alt?: string
  size?: number | string
  className?: string
}

export const Icon: React.FC<IconProps> = ({
  src,
  component: SVGComponent,
  alt,
  size = 24,
  className,
  ...props
}) => {
  const dimension = typeof size === 'number' ? `${size}px` : size

  if (SVGComponent) {
    return (
      <SVGComponent
        width={dimension}
        height={dimension}
        className={cn('inline-block', className)}
        {...(props as React.SVGProps<SVGSVGElement>)}
      />
    )
  }

  return (
    <img
      src={src}
      alt={alt}
      width={typeof size === 'number' ? size : undefined}
      height={typeof size === 'number' ? size : undefined}
      style={typeof size === 'string' ? { width: dimension, height: dimension } : undefined}
      className={cn('object-contain', className)}
      {...props}
    />
  )
}
  • Icon 커스텀 컴포넌트에서 img파일의 경우 src경로로 인자를 받고, svg파일의 경우 SVGComponent 형식의 데이터를 받아서 렌더링 한다.

Icon 컴포넌트 사용법

import CheckIcon from '@/assets/voteCheckIcon.svg?react'
import { Icon } from '@/components/Icon/icon'

    <Icon
         component={CheckIcon}
         className="w-[27px] h-8 absolute right-2 top-1/2 transform -translate-y-1/2
    />
```

### 🤔 향후 대응 방안

- Icon을 공통 컴포넌트로 사용중이기에 문제가 발생한다면 확장하는 방향으로 개선 가능

### 💬 회고

- svg가 레스터화 과정에서 손상되어 모바일에서 보이지 않는 경우가 처음이었다. 항상 SVGComponent로 사용했기 때문이다. 초기 세팅과정에서 svg설정을 까먹은게 실수였다.
Clone this wiki locally