혼자 적어보는 노트

[Next.js] SVGR 으로 SVG 파일 다루기 본문

NextJS

[Next.js] SVGR 으로 SVG 파일 다루기

jinist 2022. 10. 5. 07:30

 

 

이전에 2개의 프로젝트를 진행하면서 SVG파일의 경우 img태그로 불러와서 처리를 했었는데 size는 컨트롤 할 수 있었으나 img로 svg를 불러올 경우 컬러 변경이 안되기 때문에 각 컬러별로  svg파일을 불러왔었다.

 

노가다의 현장.. 😅

 

이렇게 하다보니 여간 불편한게 아니었고 실무에서는 왠지 이렇게 사용할 것 같지가 않았다..

 

때마침 새로운 프로젝트를 진행하며 나와 비슷한 시행착오를 겪었던 팀원을 만나게 되었고, 그 팀원분이 SVG Icon 컴포넌트를 담당해서 맡아주시기로 했고 공유를 해주셨다.🙌

 

SVGR

svgr은 svg 파일을 React 컴포넌트로 변환을 시켜주는 라이브러리이다.

 

// assets/icons/close.svg

<svg viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
  <path d="M9.5 0.5L0.5 9.5M0.5 0.5L9.5 9.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" />
</svg>

이런 svg파일을 아래와 같은 컴포넌트 형태로 만들어준다.

 

import * as React from 'react'

const SvgComponent = (props) => (
    <svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg" {...props}>
      <path d="M9.5 0.5L0.5 9.5M0.5 0.5L9.5 9.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" />
    </svg>
)

export default SvgComponent

 

여기서 props를 그대로 svg에 전달하기 때문에 컴포넌트형태로 사용하면서도 관련 속성들을 지정할 수 있다.

 

import Close from '../assets/icons/close.svg';

const Example = () => (
  <div>
    <Close />
  </div>
)

 

 

Next.js에서는 config 설정 한번으로 비교적 간단하게 적용해볼 수 있었다.

 

 

svg 사이즈 및 색상 지정

 

svg를 직접 만들어서 저장하게되면 width, height값과 같이 지정된 값이 적혀있는 경우들이 있는데

지정되어 있으면 props로 넘기는 값이 제대로 적용되지 않는다.

 

// svg 파일
<svg width="75" height="75" viewBox="0 0 75 75" fill="none" xmlns="http://www.w3.org/2000/svg">


// 컴포넌트로 사용
<Alert width="50" height="50" />

 

이렇게 짤리는 현상 발생

내부의 fill 속성과 stroke 속성도 마찬가지인데

svg태그 안에 태그들에 이미 값이 지정되어 있으면 적용이 안된다.

 

그래서 예를 들어 위와 같은 아이콘이 있을 경우 ! 모양은 white로 그대로 가져가고 배경 컬러만변경을 하려면

currentColor를 사용하여 외부에서 지정을 해줄 수 있다.

// svg 파일
<svg viewBox="0 0 75 75" xmlns="http://www.w3.org/2000/svg">
<circle cx="37.5" cy="37.5" r="37.5" fill="currentColor"/>
<path d="M33 26C33 23.7909 34.7909 22 37 22C39.2091 22 41 23.7909 41 26V39C41 41.2091 39.2091 43 37 43C34.7909 43 33 41.2091 33 39V26Z" fill="white"/>
<path d="M33 50C33 47.7909 34.7909 46 37 46C39.2091 46 41 47.7909 41 50C41 52.2091 39.2091 54 37 54C34.7909 54 33 52.2091 33 50Z" fill="white"/>
</svg>


// 컴포넌트
<Alert width="50" height="50" color="red" />

 

 

stroke

배경 색상이 아닌 stroke로 이루어진 svg의 경우 path의 stroke에 currentColor를 넣어서 props의 color를 통해 색상을 지정할 수 있다.

 

// svg 파일
<svg viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13 1L1 13M1 1L13 13" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>


// 컴포넌트
<Close width="50" height="50" color="blue" />

 

* path의 stroke속성 부분을 지우고 컴포넌트의 props로 stroke를 전달해서 색상을 변경할 수 있겠지만

이렇게되면 stroke의 연관속성인 stroke-width, stroke-linecap 등이 적용되지 않는다.

=> 처음엔 잘 몰라서 stroke에 직접 컬러를 지정했었는데 이 때 팀원분이 currentColor를 알려주셨었다 😀

// svg 파일
<svg viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13 1L1 13M1 1L13 13" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>


// 컴포넌트
<Close width="50" height="50" stroke="blue" /> // color를 stroke로 할 경우

 

 

Icon컴포넌트

위의 내용들을 조합하여 svg파일의 컬러와 사이즈를 변경할 수 있는 Icon 컴포넌트를 구현할 수 있게 되었다.

// icon/svg.ts

export { default as Close } from '~/assets/icons/close.svg';
export { default as Comment } from '~/assets/icons/comment.svg';


// icon/index.tsx
import * as icons from './svg';

한 파일에서 아이콘을 모두 export 한 후 icon컴포넌트를 구현할 index.tsx 파일에서 icons를 불러와서 지정된 이름에 맞게 사용할 수 있다.

이렇게 불러온 icons는 module 객체이기 때문에 icons.[컴포넌트명]으로 사용할 수 있다.

이 부분 몰랐는데 알게 되었다.👍

 

 

++

비교적 단순한 아이콘들만 추가를 했을 땐 크게 문제는 없었지만 조금 복잡한 형태의 아이콘을 다루게 될 경우

SVG파일의 코드를 조금 손봐야되는 일들이 생기긴 했다. figma에서 아이콘을 저장했는데 생각처럼 동작하지 않아서

필요없는 코드를 지우고 viewbox를 수정해가며 맞췄다. @.@

 

viewBox에 관한 참고글

 

아직 완벽히 이해가 된 것 같지 않아서 조금 더 공부를 해야될 것 같다😂 어려운 SVG!

'NextJS' 카테고리의 다른 글

[Next.js] Rewrites  (0) 2022.11.06
[Next.js] MSW로 API 모킹하기  (0) 2022.10.13
[Next.js] Shallow: true 뒤로가기 시 데이터 패칭  (0) 2022.08.31
[Next.js] 페이지 이동 시 로딩  (0) 2022.08.19
[Next.js] 카카오톡 공유하기  (0) 2022.08.13
Comments