¿El SVG en Base64 no se muestra? Así se soluciona bien
Este problema aparece constantemente en proyectos reales:
- Tu
img src="data:image/svg+xml;base64,..."parece válido, pero no se renderiza nada. - La misma cadena SVG funciona en un lugar y falla en un fondo CSS.
- El bug es difícil de detectar en una code review, pero caro de depurar.
Si esto te resulta familiar, esta guía te da una forma clara y repetible de resolverlo.
Por qué es difícil de depurar
El problema rara vez está en una sola línea rota. Normalmente es una cadena de fallos:
- La fuente SVG ya puede ser inválida.
- La codificación puede no coincidir con el contexto de destino.
- HTML, CSS y JSON requieren comportamientos de escape distintos.
- La limpieza de seguridad y las reglas de renderizado varían según el entorno.
Por eso un mismo SVG puede renderizarse en un contexto y fallar en otro.
Causas raíz más comunes (en orden de prioridad)
-
Prefijo MIME incorrecto
Usadata:image/svg+xml;base64,odata:image/svg+xml,. -
Flujo de codificación Base64 incorrecto
btoa(svg)directamente puede fallar cuando el SVG contiene caracteres no ASCII. -
Desajustes de escape entre contextos
Especialmente en CSS, caracteres como#y las comillas pueden romper la carga. -
Contenido SVG arriesgado o bloqueado
Los scripts, controladores de eventos y referencias externas pueden eliminarse o bloquearse. -
Estructura SVG rota
La falta deviewBox, XML mal formado o etiquetas no válidas pueden impedir el renderizado.
Cómo lo resolvemos en SVGView
En lugar de obligar al usuario a adivinar, lo resolvemos en tres capas claras.
1) Capa de entrada: validar antes de importar
En src/lib/svg/import-handler.ts, hacemos lo siguiente:
- aplicamos tipo y tamaño de archivo (hasta 10 MB)
- analizamos y validamos XML con una raíz
<svg>obligatoria - devolvemos errores de parseo para un diagnóstico más rápido
Esto descarta pronto las entradas inválidas.
2) Capa de seguridad: sanear antes de previsualizar
En src/lib/svg/sanitizer.ts, eliminamos:
<script>- atributos de controladores de eventos
on* <foreignObject>- referencias externas (
href,xlink:href,src)
Esto mejora la seguridad y reduce la inconsistencia de renderizado.
3) Capa de salida: ofrecer Data URI tanto en Base64 como con URL encoding
En 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}`;
}
Así puedes:
- elegir Base64 para una compatibilidad más segura
- elegir URL encoding para una salida más corta y legible
- obtener siempre el tipo MIME correcto
image/svg+xml
¿Qué codificación deberías usar?
- Entorno de destino desconocido: elige primero Base64
- Necesitas cadenas más cortas y legibles: elige URL encoding
- Uso como fondo CSS: prefiere URL encoding con el escape adecuado
Usa estas herramientas directamente:
Un checklist de resolución de problemas repetible
- Confirma el prefijo:
data:image/svg+xml;base64,odata:image/svg+xml, - Confirma una raíz
<svg>válida y unviewBox - Confirma un flujo de codificación seguro para UTF-8
- Confirma el escape para contextos CSS/JSON
- Sanea antes de exportar
- Alterna entre Base64 y URL encoding para contrastar rápidamente
FAQ
¿Por qué funciona en <img> pero falla en CSS?
Porque el parseo de cadenas en CSS tiene requisitos de escape más estrictos. El URL encoding suele ser más seguro ahí.
¿Cambiar a image/svg+xml siempre es suficiente?
No. El MIME es solo una parte. La codificación, el escape y la validez del SVG siguen importando.
¿Un Data URI es siempre mejor que archivos SVG externos?
No. Los Data URI son excelentes para recursos inline pequeños. Los recursos grandes o muy reutilizados suelen funcionar mejor como archivos externos.
Resumen
“SVG Base64 no se muestra” no es un único bug. Es un problema de canalización.
Cuando estandarizas el flujo como validar -> sanear -> doble codificación -> ajuste al contexto, el problema se vuelve mucho más predecible y manejable.