Skip to content

Hook for optimizing SVGs before inlining them? #19945

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
4 tasks done
retorted opened this issue Apr 26, 2025 · 2 comments
Open
4 tasks done

Hook for optimizing SVGs before inlining them? #19945

retorted opened this issue Apr 26, 2025 · 2 comments

Comments

@retorted
Copy link

retorted commented Apr 26, 2025

Description

Hi, I'm working on a project that pulls in a considerable number of SVGs from an external package and inlines them in CSS as data-urls. It works great, but a lot of the SVGs are not optimized and they have a lot of junk in them. Their size could be roughly cut in half if some of the useless bits were stripped out.

Is there a way to modify an SVG at the point it's being inlined? Or would it be possible to add some kind of hook so that the content could be stripped/optimized before it's inlined?

Suggested solution

I'm thinking of a callback here that gives access to the stringContent to allow an additional Regex or custom transformation to be applied before the content gets transformed/escaped:

function svgToDataURL(content: Buffer): string {
const stringContent = content.toString()
// If the SVG contains some text or HTML, any transformation is unsafe, and given that double quotes would then
// need to be escaped, the gain to use a data URI would be ridiculous if not negative
if (
stringContent.includes('<text') ||
stringContent.includes('<foreignObject') ||
nestedQuotesRE.test(stringContent)
) {
return `data:image/svg+xml;base64,${content.toString('base64')}`
} else {
return (
'data:image/svg+xml,' +
stringContent
.trim()
.replaceAll(/>\s+</g, '><')

Eg:

function svgToDataURL(content: Buffer): string { 
   const stringContent = content.toString() 

   const { beforeInlineSvg } = environment.config.build
   if (typeof beforeInlineSvg === 'function') {
      stringContent = beforeInlineSvg(stringContent)
   }
   
   ... 

Alternative

No response

Additional context

No response

Validations

@jiikoosol
Copy link

Have you tried Vite SVG Loader? https://github.com/jpkleemans/vite-svg-loader
You can use SVGO to optimize SVG-files before inlining them.

@retorted
Copy link
Author

That works for importing SVGs as static assets, but not for dynamically inlining SVGs from external libraries, right? Or have I missed something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants