React와 Next.js에서 SVG 사용하기: 완전한 통합 가이드
React와 Next.js 애플리케이션에서의 SVG 통합을 마스터하세요. 가져오기 방법, 컴포넌트 패턴, 최적화, 모던 웹 개발을 위한 모범 사례를 배울 수 있습니다.

Founder of VectoSolve
Self-taught developer, founder and sole developer of VectoSolve since 2024. He builds the conversion engine and the cutting, embroidery and 3D printing exports.
How this article was made: drafted with AI assistance, then edited and fact-checked before publication. About the author
Key Takeaways
- React는 4가지 주요 SVG 가져오기 방법을 제공합니다: 이미지 import, 인라인 SVG, SVGR 컴포넌트, 동적 import
- Next.js webpack 설정과 함께하는 SVGR이 개발자 경험과 런타임 제어 사이의 최적 균형을 제공합니다
- TypeScript props(size, color, className)를 가진 재사용 가능한 아이콘 컴포넌트가 코드를 DRY하게 유지합니다
- Framer Motion은 SVG 요소와 네이티브로 통합되어 스프링 기반 경로 및 모양 애니메이션을 제공합니다
-
스크린 리더 접근성을 위해 SVG 아이콘에 항상
aria-label또는aria-hidden을 추가하세요
모던 React 개발에서의 SVG
SVG는 모던 React 애플리케이션에 필수적이며, 어떤 크기에서도 선명한 그래픽을 제공합니다. 이 가이드는 React와 Next.js 프로젝트에서 SVG를 사용하는 모든 방법을 다룹니다.
가져오기 방법
1. 표준 이미지 Import
가장 간단한 접근법:
import logo from './logo.svg';
function Header() {
return <img src={logo} alt="로고" className="logo" />;
}
장점: 간단, 익숙함
단점: 스타일링/조작 접근 불가
2. 인라인 SVG 컴포넌트
완전한 제어:
function Icon() {
return (
<svg viewBox="0 0 24 24" className="icon">
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5"/>
</svg>
);
}
장점: CSS/JS 완전 접근
단점: 장황함, 소스 변경 어려움
3. SVGR (React 컴포넌트)
컴포넌트로 가져오기:
import { ReactComponent as Logo } from './logo.svg';
function Header() {
return <Logo className="logo" fill="currentColor" />;
}
장점: 두 세계의 장점
단점: 설정 필요
4. 동적 Import
코드 분할용:
import dynamic from 'next/dynamic';
const DynamicIcon = dynamic(() => import('./icons/chart.svg'));
function Dashboard() {
return <DynamicIcon />;
}
Pro Tip: 대부분의 React 프로젝트에서 SVGR이 권장 접근법입니다. SVG 파일을 디자인 도구에서 쉽게 편집할 수 있도록 별도로 유지하면서, 전체 prop 지원과 함께 React 컴포넌트로 SVG를 가져올 수 있습니다.
SVGR 설정
Next.js 설정
// next.config.js
module.exports = {
webpack(config) {
config.module.rules.push({
test: /\.svg$/,
use: ['@svgr/webpack'],
});
return config;
},
};
URL 폴백 포함
// next.config.js
module.exports = {
webpack(config) {
config.module.rules.push({
test: /\.svg$/,
issuer: /\.[jt]sx?$/,
use: [
{
loader: '@svgr/webpack',
options: {
svgoConfig: {
plugins: [{
name: 'removeViewBox',
active: false
}]
}
}
},
'url-loader'
],
});
return config;
},
};
A Full Year of Conversions for $49
Starter Annual: 25 conversions every month, $49 for the whole year. That is about $4.08 a month · Cancel anytime
Get the Annual Deal컴포넌트 패턴
재사용 가능한 아이콘 컴포넌트
interface IconProps {
name: string;
size?: number;
color?: string;
className?: string;
}
export function Icon({ name, size = 24, color = 'currentColor', className }: IconProps) {
return (
<svg
width={size}
height={size}
fill={color}
className={className}
>
<use href={`/sprites.svg#${name}`} />
</svg>
);
}
// 사용 예
<Icon name="search" size={20} color="#333" />
아이콘 라이브러리 컴포넌트
// icons/index.tsx
import { FC, SVGProps } from 'react';
interface IconComponentProps extends SVGProps<SVGSVGElement> {
size?: number;
}
const createIcon = (path: string): FC<IconComponentProps> => {
return function IconComponent({ size = 24, ...props }) {
return (
<svg
viewBox="0 0 24 24"
width={size}
height={size}
fill="currentColor"
{...props}
>
<path d={path} />
</svg>
);
};
};
export const SearchIcon = createIcon('M15.5 14h-.79l-.28-.27...');
export const HomeIcon = createIcon('M10 20v-6h4v6h5v-8h3L12...');
React에서 SVG 스타일링
CSS 스타일링
/* styles.css */
.icon {
width: 24px;
height: 24px;
fill: currentColor;
transition: fill 0.2s;
}
.icon:hover {
fill: #0066cc;
}
Styled Components
import styled from 'styled-components';
const StyledSvg = styled.svg`
width: ${props => props.size || 24}px;
height: ${props => props.size || 24}px;
fill: ${props => props.color || 'currentColor'};
transition: fill 0.2s;
&:hover {
fill: ${props => props.hoverColor || props.color};
}
`;
Tailwind CSS
<svg
className="w-6 h-6 fill-current text-gray-600 hover:text-blue-500 transition-colors"
viewBox="0 0 24 24"
>
<path d="..."/>
</svg>
"React에서 최고의 SVG 워크플로우는 디자이너가 깨끗한 벡터를 내보내고 개발자가 이를 일급 컴포넌트로 가져오는 — 사이에 수동 변환 단계가 없는 워크플로우입니다.
React에서의 애니메이션
CSS 애니메이션
function LoadingSpinner() {
return (
<svg className="animate-spin" viewBox="0 0 24 24">
<circle
className="opacity-25"
cx="12" cy="12" r="10"
stroke="currentColor" strokeWidth="4"
/>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
/>
</svg>
);
}
Framer Motion
import { motion } from 'framer-motion';
function AnimatedIcon() {
return (
<motion.svg
viewBox="0 0 24 24"
initial={{ scale: 0 }}
animate={{ scale: 1 }}
transition={{ type: 'spring' }}
>
<motion.path
d="M12 2L2 22h20L12 2z"
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
/>
</motion.svg>
);
}
Free SVG Tools for Crafters
Design Checker · Color Separator · Mat Preview · Offset Generator · Text to SVG
Check Your SVG Free최적화 전략
빌드 타임 최적화
// svgo.config.js
module.exports = {
plugins: [
'preset-default',
'removeDimensions',
{ name: 'removeViewBox', active: false },
{ name: 'prefixIds', params: { prefix: 'svg-' } }
]
};
코드 분할
// 무거운 아이콘 지연 로딩
const ChartIcon = lazy(() => import('./icons/Chart'));
function Dashboard() {
return (
<Suspense fallback={<div className="icon-placeholder" />}>
<ChartIcon />
</Suspense>
);
}
SVGO 최적화 중에 viewBox를 절대 제거하지 마세요. viewBox가 없으면 SVG는 반응형 스케일링 능력을 잃습니다. SVGO 설정에서 항상 removeViewBox: false를 설정하세요.
React에서의 접근성
접근 가능한 아이콘 패턴
interface AccessibleIconProps {
label: string;
children: React.ReactNode;
}
function AccessibleIcon({ label, children }: AccessibleIconProps) {
return (
<span role="img" aria-label={label}>
{children}
</span>
);
}
// 사용 예
<AccessibleIcon label="검색">
<SearchIcon />
</AccessibleIcon>
아이콘 버튼
function IconButton({ icon: Icon, label, onClick }) {
return (
<button
onClick={onClick}
aria-label={label}
className="icon-button"
>
<Icon aria-hidden="true" />
</button>
);
}
VectoSolve 통합
워크플로우
VectoSolve를 React와 함께 사용:
- 이미지를 SVG로 변환
- 최적화된 출력 다운로드
- React 프로젝트에 가져오기
- 위의 선호하는 방법 사용
최적화 파일의 장점
VectoSolve SVG는:
- 웹 사용에 최적화
- SVGR import 준비 완료
- 깨끗한 경로 데이터
- 스타일링이 쉬움
A Full Year of Conversions for $49
Starter Annual: 25 conversions every month, $49 for the whole year. That is about $4.08 a month · Cancel anytime
Get the Annual Deal결론
React는 SVG와 작업하는 여러 방법을 제공하며, 각각 트레이드오프가 있습니다. 필요에 맞는 접근법을 선택하세요: 기본 사용에는 간단한 이미지 import, 완전한 제어에는 SVGR, 아이콘 시스템에는 컴포넌트 패턴. 최상의 결과를 위해 VectoSolve의 깨끗하고 최적화된 SVG로 시작하세요.
| SVG Import 방법 | 런타임 제어 | 번들 영향 | 최적 용도 |
|---|---|---|---|
| <img src> import | 없음 | 별도 HTTP 요청 | 정적 장식 이미지 |
| 인라인 JSX SVG | 완전 (props, 이벤트, CSS) | 컴포넌트 크기 증가 | 인터랙티브 아이콘, 애니메이션 |
| SVGR 컴포넌트 | 완전 (타입 props, 트리 쉐이킹) | 컴포넌트별 청크 | 아이콘 라이브러리, 디자인 시스템 |
| 동적 import | 완전 (로딩 후) | 코드 분할, 지연 로딩 | 폴드 아래 또는 조건부 SVG |
참고 자료 및 추가 읽기
- MDN Web Docs: SVG in HTML — JSX에 SVG 삽입 및 SVG-DOM 상호작용 이해를 위한 참조
- web.dev: Code Splitting — 최적 번들 크기를 위한 지연 로딩과 동적 import에 대한 Google 가이드
- CSS-Tricks: SVG in React — React와 Next.js 프로젝트에서 SVG 컴포넌트를 사용하기 위한 실용 패턴
- Smashing Magazine: React Components — 재사용 가능하고 접근 가능한 SVG 컴포넌트 라이브러리 구축을 위한 모범 사례