Auto generate IDs (for <defs>) during render, with SSR support #1
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
One common complaint is that rendering the same SVG multiple times results in duplicate IDs on the page. See airbnb#57.
IDs are pretty much necessary for using things like gradients. The problem is since the SVG is rendered inline, and sometimes the same SVG is rendered multiple times, the IDs are duplicated on the page. This is not only invalid, but results in actual bugs.
For example, let's say one of the SVGs becomes hidden:
Did you know hiding the elements that
url(#foo)
references in an SVG cause their referents to also hide (in some browsers at least)? Yeah, weird. Even though the ID'd elements are still in the DOM, hiding them causes their reference to hide also.In our case, we are rendering country flag icons both in a dropdown and in a footer. When the dropdown is hidden, so are all the flags in the footer.
This patch adds runtime code similar to Reach UI's Auto ID. NOTE THAT THIS MEANS YOU'LL NEED TO CHANGE
babel-plugin-inline-react-svg
TO BE INdependencies
, NOTdevDependencies
. All IDs are replaced with references to the (newly built-in)useId()
hook. This ensures that you can render the same SVG as many times as you like, and each instance will have unique IDs.If using server-side rendering (SSR), you can wrap your app in the
<AutoIdProvider>
that's also exported, which will ensure that the IDs match up during hydration.Would using
<use>
and/or shared non-hidden<defs>
be technically better?Yes, but extremely complicated. This requires a central manager and portals, which are both quite difficult for SSR (we'd need some specialized helper like
react-helmet
ornext/head
, except for stuff in<body>
instead of<head>
).Fixes airbnb#57.