SVG 아이콘을 컴포넌트처럼 사용하려고 @svgr/webpack 설정을 적용했는데,
이상하게도 width, height, cursor, fill 같은 스타일이 전혀 먹히지 않던 경험 있으신가요?
저도 정확히 이 문제를 겪었고, 해결 방법은 단순했지만 이유는 조금 복잡했습니다.
Next.js에서 SVG를 아이콘 컴포넌트처럼 사용하고자 Babel 플러그인(inline-react-svg)을 제거하고,
대신 공식적으로 더 권장되는 @svgr/webpack 방식으로 전환했습니다. 그런데 전환 이후, 어떠한 스타일도 적용되지 않는 문제가 발생했습니다.
기존에 SVG를 다음과 같이 사용했습니다:
import ArrowIcon from '@/assets/arrow.svg'
<StyledButton>
<ArrowIcon />
</StyledButton>
그리고 styled-components로 아래와 같이 스타일을 적용했습니다:
const StyledButton = styled.button`
svg {
width: 30px;
height: 30px;
cursor: pointer;
}
`
위 방식은 Babel 플러그인(inline-react-svg)으로 작성 되었을 때는 svg 테그가 JSX 인라인으로 삽입되기 때문에 styled-components, SCSS, CSS Module 등 외부 스타일이 자유롭게 적용될 수 있었습니다.
하지만 더 나은 타입 지원과 유지보수를 위해 @svgr/webpack을 도입하고
.babelrc 및 inline-react-svg 설정을 제거한 뒤 다음처럼 설정을 바꾸자,
브라우저에서 SVG에 적용한 스타일이 전혀 반영되지 않았습니다.
아이콘 크기도 변하지 않고, 커서도 default, 심지어 fill 색상도 적용되지 않음.
// next.config.js
config.module.rules.push({
test: /\.svg$/,
issuer: /\.[jt]sx?$/,
use: [
{
loader: '@svgr/webpack',
options: {
svgo: false, // ✅ 최적화 비활성화
titleProp: true,
ref: true,
},
},
]
})
SVGR은 SVG 파일을 React 컴포넌트로 변환할 때, 내부적으로 SVGO라는 최적화 도구를 사용합니다.
이 도구는 width, height, fill, cursor, pointer-events 같은 속성을 삭제하거나 style 속성으로 이동시켜 버립니다.
그 결과, 외부에서 styled-components나 CSS로 지정한 스타일이 덮어쓰기(override) 되지 않게 되는 것이죠.
즉, 스타일이 적용되지 않는 이유는 SVG 내부 속성이 최적화되면서 사라졌기 때문입니다.
Next.js에서 SVG 스타일이 적용되지 않는다면,
next.config.js에서 svgo: false 설정을 꼭 확인하세요.
이 작은 설정 하나만으로도, Babel 없이도 인라인 SVG처럼 자유로운 스타일링을 다시 할 수 있습니다.