question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Multiple inline SVGs on a page can clash

See original GitHub issue

Have you read the Contributing Guidelines on issues?

Prerequisites

  • I’m using the latest version of Docusaurus.
  • I have tried the npm run clear or yarn clear command.
  • I have tried rm -rf node_modules yarn.lock package-lock.json and re-installing packages.
  • I have tried creating a repro with https://new.docusaurus.io.
  • I have read the console error message carefully (if applicable).

Description

Including multiple inline SVGs on a page like so:

import FooSvg from '@site/static/img/foo.svg';
import BarSvg from '@site/static/img/bar.svg';

export default function SomePage() {
  return (
    <div>
      <FooSvg />
      <BarSvg />
    </div>
  );

can result in the SVGs clashing with each other if those SVGs use ids internally.

The reason the inline SVGs aren’t working is because of the way Docusaurus has configured its SVG loader internally. Docusaurus uses the Webpack loader for SVGR. SVGR in turn uses SVGO. By default, SVGO minifies SVG ids. When those ids get minified to single characters (like “a”, “b”, “c”), they can clash on the page. SVGO has an option to prefix ids, but Docusaurus has not turned that option on. I created a minimal reproduction of the bug. You can comment out one SVG at a time from the source code, and see that when only one SVG is on the page, it renders properly. But when both are on the page, one clashes with the other.

I think one possible way to fix this would be to add the SVGO option prefixIds: true just below line 123 in webpackUtils.ts.

Reproducible demo

https://stackblitz.com/edit/github-ptytnu?file=src/pages/index.js

Steps to reproduce

All I did to create the minimal repro was to start with a fresh Docusaurus install using new.docusaurus.io, upload two SVGs that I know clash, then import and render those two SVGs into the existing index page.

Expected behavior

The SVGs should look the way they look when rendered individually.

Actual behavior

The SVGs are colored and painted incorrectly because the gradients or masks in one SVG are being applied on top of another.

Your environment

If you wish to dig in more, you can look at the history of the pull request I was working on when I ran into this bug:

Self-service

  • I’d be willing to fix this bug myself.

Issue Analytics

  • State:open
  • Created 10 months ago
  • Comments:15

github_iconTop GitHub Comments

1reaction
vimwitchcommented, Nov 22, 2022

This bug is nasty and cost ~5 hours on what should have been a 10 minute task. I think the approach you are considering here is wrong. Instead of enabling prefixIds, why not disable cleanupIds?

cleanupIds minifies ids without consideration of the global context. Most editing tools already include id minification and prefix additions. Disabling the cleanupIds option delegates id management to the export tool. It also reduces confusion about how SVGs are processed by webpack (e.g. ids are left alone). Maybe it’s not a perfect long term solution, but seems simple/backward compatible enough that it could be pushed through quickly.

Enabling both cleanupIds and prefixIds seems insane to me. Are the prefixes random? How much entropy is there? If i add 100 svgs each with 10,000 ids am I risking an id collision?? Less magic in the processing = less stuff to debug.

On a related note, enabling id minification without handling collisions seems like an insane default from svgo.

1reaction
Josh-Cenacommented, Nov 10, 2022

Can turning this on cause troubles for existing users?

In fact, users can’t target SVG IDs with external CSS—SVGO removes all unreferenced IDs. This can be symphasized with—all tools I know (i.e. Inkscape, Illustrator) add an ID to literally every path, so it’s mostly useless.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Multiple inline SVG in HTML not displayed correctly
The problem is almost certainly a clash of id attributes. The id attributes need to be unique on the page. But I expect...
Read more >
Multiple Inline SVGs (From QuickChart) - Jim Nielsen's Blog
But this SVG document is embedded in an HTML document with other SVG documents using the same IDs, so they clash. “Just reference...
Read more >
Problems with multiple SVG inlined on same page due to ...
When you have two embedded svgs on the same page, the style tags that are contained in each svg can conflict... often because...
Read more >
The Best Way to Embed SVG on HTML (2021) - Vecta.io
Ideally our SVG should be easy to maintain, just create and embed without the need to ensure their classes and IDs do not...
Read more >
Using SVGs on the Web — A Deep Dive - Level Up Coding
SVGs can contain classes and IDs, which should not clash with these attributes on other SVGs on the page. SVG implementation methods. Now...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found