블로그로 돌아가기

Base64 SVG가 표시되지 않을 때: 실무에서 바로 쓰는 해결 가이드

HTML/CSS에서 Base64 SVG가 실패하는 이유와 SVGView가 검증, sanitization, 이중 인코딩 출력으로 이를 해결하는 방식을 정리한 실전 가이드입니다.

2026년 2월 6일SVGData URIBase64프런트엔드 엔지니어링사용자 경험SVGView

Base64 SVG가 표시되지 않을 때: 실무에서 바로 쓰는 해결 가이드

이 문제는 실제 프로젝트에서 정말 자주 발생합니다.

  • img src="data:image/svg+xml;base64,..."가 문법상 맞아 보여도 아무것도 렌더링되지 않습니다.
  • 같은 SVG 문자열이 한 곳에서는 동작하지만 CSS 배경에서는 깨집니다.
  • 코드 리뷰에서는 놓치기 쉽지만, 디버깅 비용은 크게 듭니다.

익숙한 상황이라면 이 가이드가 재현 가능한 해결 경로를 제시해 줄 수 있습니다.

왜 디버깅이 어려운가

대부분 한 줄짜리 버그가 아닙니다. 보통은 여러 단계가 얽힌 문제입니다.

  1. SVG 원본 자체가 이미 잘못되어 있을 수 있습니다.
  2. 인코딩 방식이 사용하려는 대상 환경과 맞지 않을 수 있습니다.
  3. HTML, CSS, JSON은 서로 다른 이스케이프 규칙을 요구합니다.
  4. 보안 정리와 렌더링 규칙이 환경마다 다릅니다.

그래서 같은 SVG가 어떤 곳에서는 보이고, 다른 곳에서는 실패합니다.

가장 흔한 원인 우선순위

  1. 잘못된 MIME 접두사
    data:image/svg+xml;base64, 또는 data:image/svg+xml,를 사용해야 합니다.

  2. 잘못된 Base64 인코딩 흐름
    SVG에 비 ASCII 문자가 포함되면 단순 btoa(svg)는 깨질 수 있습니다.

  3. 컨텍스트별 이스케이프 불일치
    특히 CSS에서는 #, 따옴표 같은 문자가 로딩을 깨뜨릴 수 있습니다.

  4. 위험하거나 차단된 SVG 내용
    스크립트, 이벤트 핸들러, 외부 참조는 제거되거나 차단될 수 있습니다.

  5. 손상된 SVG 구조
    viewBox 누락, 잘못된 XML, 유효하지 않은 태그가 렌더링을 막을 수 있습니다.

SVGView에서 이 문제를 해결하는 방식

사용자에게 추측하게 두지 않고, 세 단계로 처리합니다.

1) 입력 레이어: import 전에 검증

src/lib/svg/import-handler.ts에서 다음을 수행합니다.

  • 파일 타입과 크기 제한 적용 (최대 10MB)
  • <svg> 루트가 있는지 XML 파싱 및 검증
  • 파싱 오류를 빠르게 반환

이 단계에서 잘못된 입력을 일찍 걸러냅니다.

2) 안전 레이어: 미리보기 전에 정리

src/lib/svg/sanitizer.ts에서 다음을 제거합니다.

  • <script>
  • on* 이벤트 핸들러 속성
  • <foreignObject>
  • 외부 참조 (href, xlink:href, src)

이렇게 하면 보안이 좋아지고 렌더링 불일치도 줄어듭니다.

3) 출력 레이어: Base64와 URL 인코딩 Data URI를 모두 제공

src/lib/svg/exporter.ts에서는 다음과 같이 처리합니다.

export function exportToDataUri(svg: string): string {
  const encoded = btoa(unescape(encodeURIComponent(svg)));
  return `data:image/svg+xml;base64,${encoded}`;
}

export function exportToDataUriEncoded(svg: string): string {
  const encoded = encodeURIComponent(svg);
  return `data:image/svg+xml,${encoded}`;
}

그래서 다음이 가능합니다.

  • 호환성을 우선하면 Base64 선택
  • 더 짧고 읽기 쉬운 문자열이 필요하면 URL 인코딩 선택
  • 항상 올바른 image/svg+xml MIME 타입 유지

어떤 인코딩을 선택해야 하나

  1. 대상 환경이 불확실할 때: 먼저 Base64를 선택합니다.
  2. 더 짧고 읽기 쉬운 문자열이 필요할 때: URL 인코딩을 선택합니다.
  3. CSS background에 쓸 때: 적절히 이스케이프한 URL 인코딩이 보통 더 안전합니다.

관련 도구:

재현 가능한 문제 해결 체크리스트

  1. 접두사 확인: data:image/svg+xml;base64, 또는 data:image/svg+xml,
  2. 유효한 <svg> 루트와 viewBox 존재 여부 확인
  3. UTF-8 안전 인코딩 흐름 확인
  4. CSS/JSON 컨텍스트용 이스케이프 확인
  5. 내보내기 전 sanitization 수행
  6. Base64와 URL 인코딩을 번갈아 테스트해 빠르게 비교

FAQ

<img>에서는 되는데 CSS에서는 실패하나요?

CSS 문자열 파싱은 더 엄격한 이스케이프 규칙을 요구합니다. 보통 URL 인코딩이 더 안전합니다.

image/svg+xml로 바꾸기만 하면 항상 해결되나요?

아닙니다. MIME 타입은 일부일 뿐입니다. 인코딩, 이스케이프, SVG 자체의 유효성도 모두 중요합니다.

Data URI가 외부 SVG 파일보다 항상 더 좋은가요?

아닙니다. 작은 인라인 자산에는 좋지만, 크거나 여러 번 재사용되는 자산은 외부 파일이 더 나을 때가 많습니다.

정리

"Base64 SVG가 표시되지 않는다"는 하나의 버그가 아니라 파이프라인 문제입니다.

검증 -> sanitization -> 이중 인코딩 -> 컨텍스트 매칭 흐름을 표준화하면, 문제를 훨씬 더 예측 가능하게 다룰 수 있습니다.

관련 기사

SVG 워크플로우와 제작 팁을 계속 살펴보세요.