[트러블슈팅] Toastify CSS가 적용되지 않을 때 (feat. tailwind CSS)

송수빈송수빈
3 min read

이번에 Toastify를 처음 사용해봤는데 css가 적용이 안 된다🥹

utils/toastService.js

import { toast } from 'react-toastify'

const defaultOptions = {
  position: 'top-center',
  autoClose: 2000,
  hideProgressBar: false,
  closeOnClick: true,
  pauseOnHover: true,
  draggable: true,
  theme: 'colored',
}

const ToastService = {
  success: (message, options = {}) =>
    toast.success(message, {
      ...defaultOptions,
      className: 'bg-pink-100 text-main-pink font-semibold rounded shadow',
      progressClassName: 'bg-main-pink',
      icon: '🌸',
      ...options,
    }),

  error: (message, options = {}) =>
    toast.error(message, {
      ...defaultOptions,
      className: 'bg-red-100 text-red-700 font-semibold rounded shadow',
      progressClassName: 'bg-red-500',
      icon: '❌',
      ...options,
    }),

  info: (message, options = {}) =>
    toast.info(message, {
      ...defaultOptions,
      className: 'bg-blue-100 text-blue-700 font-semibold rounded shadow',
      progressClassName: 'bg-blue-500',
      icon: 'ℹ️',
      ...options,
    }),

  warning: (message, options = {}) =>
    toast.warn(message, {
      ...defaultOptions,
      className: 'bg-yellow-100 text-yellow-700 font-semibold rounded shadow',
      progressClassName: 'bg-yellow-500',
      icon: '⚠️',
      ...options,
    }),
}

export default ToastService

이렇게 커스텀을 해뒀다..‼️

하지만 css가 적용이 안 된다 🙂‍↔️ (부정)

어느부분이 문제라고 생각했냐?

  • 엄청난 구글링을 통해 다양한 해결책을 적용해보았다… 하지만 단 하나도 해결방법이 되어주진 못 했다..!!! 그러던 중에 근본적으로 tailwind로 스타일을 주고 있으니 스타일을 주는 방식이 문제가 있나..?! 라는 생각을 했다.
//기존에 css 주는 방식 
error: (message, options = {}) =>
    toast.error(message, {
      ...defaultOptions,
      className: 'bg-red-100 text-red-700 font-semibold rounded shadow',
      progressClassName: 'bg-red-500',
      icon: '❌',
      ...options,
}),

그래서 기존 className 방식에서 style 방식으로 수정해줬다.

error: (message, options = {}) =>
    toast.error(message, {
      ...defaultOptions,
      style: {
        backgroundColor: '#fee2e2',
        color: '#b91c1c',
        fontWeight: '600',
        borderRadius: '0.375rem',
        boxShadow: '0 1px 2px rgba(0,0,0,0.05)',
      },
      progressStyle: {
        background: '#ef4444',
      },
      icon: '❌',
      ...options,
    }),

적용이된다.. 충격!!!! 🤦🏻‍♀️

🧐 왜 이런일이 발생했을까?

  1. Tailwind의 클래스 제거 최적화

Tailwind CSS는 빌드할 때 사용되지 않은 CSS 클래스는 자동으로 제거한다.

이 기능을 PurgeCSS 또는 content 기반 트리 셰이킹이라고 함

// tailwind.config.js
content: ['./src/**/*.{js,jsx,ts,tsx}']

다들 분명 tailwind.config.js가 이렇게 되어 있을것임 ‼️

Tailwind는 이 경로 내에서 실제로 직접 적혀 있는 클래스명만 찾아서 빌드에 포함하는 특징이 있다.

  1. react-toastify는 동적으로 className을 적용함

    • toast.success('message', { className: 'bg-red-100 text-red-700' }) 처럼 동적으로 문자열을 전달하면 Tailwind는 이 className이 정적인 HTML/CSS/JSX 안에 없기 때문에 제거해버린다.
    toast.success('hello', {
      className: 'bg-red-100 text-red-700',
    })

는 Tailwind 입장에서 볼 때 "bg-red-100"이라는 클래스가 어디에도 직접 안 써 있으니 지워버린것이다…🥺

✅ 해결된 이유: style은 CSS를 "직접" 지정하니까!

  • style은 자바스크립트 객체로 실제 인라인 CSS를 직접 전달하기 때문에 Tailwind와는 상관없이 적용된다.

🌱 배운 점

  • Tailwind CSS는 사용되지 않은 클래스명을 자동으로 제거한다는 사실을 실제로 겪으며 이해할 수 있었다. 특히 react-toastify처럼 외부 라이브러리에서 동적으로 className을 넘기는 경우에 Tailwind의 트리 셰이킹 대상이 되어 클래스가 적용되지 않을 수 있다는 걸 알게 되었다.(Tailwind는 역시 어려워)

  • ToastContainer를 잘 넣고 ToastService도 분리해놨지만 스타일이 안 먹는 이유는 Tailwind의 빌드 방식 때문이었고 해결방법으로 style 속성으로 직접 CSS를 넣는 방식이 가장 확실하다는 것도 알게 되었다.(style최고)


💬 느낀 점

  • 글만 보면 굉장히 짧은 시간에 해결한 것처럼 보이지만, 실제로는 꽤 많은 시간을 구글링하고, Stack Overflow나 GitHub 이슈에서 제안된 다양한 방법들을 시도해봤다.

    하지만… !!! 그렇게 복잡한 해결책들 대부분은 문제를 해결해주지 못한 걸 확인하고 결국 핵심은 굉장히 기본적인 부분에 있으며 기본은 역시 중요하다는 걸 다시 한번 또 또 또 느꼈다.

  • 동적으로 className을 전달하는 방식이 Tailwind에서는 위험할 수 있다는 사실은 알고 있었지만 실제로 겪어보니 그 중요성을 더 크게 체감했다.

0
Subscribe to my newsletter

Read articles from 송수빈 directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

송수빈
송수빈