React 프로젝트를 진행하다 보면 아이콘이나 로고를 SVG 형식으로 사용하는 경우가 많다. SVG는 벡터 그래픽이기 때문에 해상도에 구애받지 않고 깔끔하게 표시되며, 크기 조절도 자유롭다. 그러나 SVG 파일을 어떻게 불러오느냐에 따라 성능과 생산성에 큰 차이가 생긴다.
이 글에서는 SVGR을 활용해 SVG를 컴포넌트로 불러오고, index.ts를 이용해 통합 관리하는 방법, 그리고 최적화를 위한 팁들을 다룬다.
<img src="...">로 불러오는 방식의 한계가장 기본적인 방식은 SVG를 이미지처럼 사용하는 것이다:
<img src="/assets/icons/arrow.svg" alt="arrow" />
이 방식은 간단하지만 단점이 많다:
fill, stroke 등을 CSS에서 조절하기 어려움title, aria-label 등 세밀한 제어 어려움SVGR은 SVG 파일을 React 컴포넌트로 변환해주는 도구이다. 예를 들어 arrow.svg를 다음과 같이 사용할 수 있게 만든다:
import { ReactComponent as ArrowIcon } from './arrow.svg';
<ArrowIcon width={24} height={24} fill="black" />
이런 방식은 다음과 같은 장점이 있다:
fill, width, height 등의 속성 조절 가능role, aria-hidden, title 등 직접 설정 가능vite.config.ts에서 SVGR을 설정하려면 다음 플러그인을 설치한다:
npm install -D @svgr/webpack
그리고 Vite에서는 다음처럼 vite-plugin-svgr을 설정한다:
npm install -D vite-plugin-svgr
// vite.config.ts
import svgr from 'vite-plugin-svgr';
export default defineConfig({
plugins: [react(), svgr()],
});
이제 .svg 파일을 다음과 같이 불러올 수 있다:
import { ReactComponent as Logo } from './logo.svg';
<Logo />
또는 단순한 URL이 필요한 경우에는 이렇게도 가능하다:
import logoUrl from './logo.svg?url';
<img src={logoUrl} alt="Logo" />
SVG 아이콘이 많아질수록 폴더 구조와 import 경로가 복잡해지기 쉽다. 이를 해결하기 위해 index.ts를 통해 아이콘을 모듈화할 수 있다.
📁 src/assets/icons
├── arrow.svg
├── search.svg
└── index.ts
// src/assets/icons/index.ts
export { ReactComponent as ArrowIcon } from './arrow.svg';
export { ReactComponent as SearchIcon } from './search.svg';
이제 컴포넌트에서는 다음처럼 사용할 수 있다:
import { ArrowIcon, SearchIcon } from '@/assets/icons';
<ArrowIcon />
<SearchIcon />
이 방식은 아이콘 관리의 일관성을 높이고 유지보수를 훨씬 수월하게 해준다.
다양한 SVG를 사용할 때 viewBox 설정이 제각각이면 아이콘 크기나 정렬이 어긋날 수 있다. 일관된 규격(예: 0 0 24 24)으로 변환해주는 툴을 사용하는 것을 권장한다.
디자인툴에서 추출한 SVG는 종종 불필요한 메타데이터, <title>, <desc>, id, class 속성 등이 포함되어 있다. 코드가 지저분해지고 렌더링에도 영향을 줄 수 있으므로 SVGO를 사용해 최적화한다.
<npm install -D svgo
npx svgo ./src/assets/icons/*.svg
SVG 내부에 fill="#000"처럼 고정된 색상이 있으면 외부에서 조절이 안 된다. 아래처럼 currentColor를 사용하면 CSS color 속성과 동기화된다.
<svg viewBox="0 0 24 24" fill="currentColor">
이렇게 하면 fill="currentColor"로 지정한 영역은 부모 컴포넌트의 color에 따라 자동으로 바뀐다.
React 컴포넌트로 변환된 SVG에도 접근성 처리는 중요하다. 아이콘이 단순 장식일 경우 aria-hidden="true"를 명시하고, 의미가 있다면 role="img"와 함께 title을 추가하자.
<ArrowIcon aria-hidden="true" />
<SearchIcon role="img" title="Search" />
SVGR을 활용하면 SVG를 더 유연하고 효율적으로 사용할 수 있으며, 코드 일관성과 유지보수성 또한 대폭 향상된다. 특히 아이콘을 index.ts로 모듈화하고, currentColor, viewBox, SVGO 등의 설정을 철저히 해두면 실무에서도 훨씬 안정적인 개발이 가능하다.