docusaurus
docusaurus copied to clipboard
Do not use React svg components for regularly used icons
Have you read the Contributing Guidelines on issues?
- [X] I have read the Contributing Guidelines on issues.
Motivation
This issue about updating the number of visible archived versions in the version dropdown lead to a weird build size diff on HTML files:
https://github.com/facebook/docusaurus/pull/5862#issuecomment-958881323
The diff in size is due to using an inlined SVG component for external links 😅 the SVG markup is duplicated in the HTML file for each item

For reusable icons of our theme, we should rather require an svg file instead of using a React SVG component, to reduce HTML output size.
It can have a significant impact on pages with a lot of icons (due to navbar, footer, doc sidebar...)
Self-service
- [ ] I'd be willing to do some initial work on this proposal myself.
Interesting discussion related to this problem: https://twitter.com/_developit/status/1382838799420514317
svg sprites look like a good solution: https://benadam.me/thoughts/react-svg-sprites/
Related read: https://fotis.xyz/posts/introducing-svg-use/
Some recent improvements for icons that are repeated multiple times per page:
- ExternalLink icon: https://github.com/facebook/docusaurus/pull/10885
- Code block button icons: https://github.com/facebook/docusaurus/pull/10866
These are the most important cases to optimize because those items are widely used in the content and/or layout.
The next things to optimize are:
- blog authors' social icons
- admonitions
These are not as widely used, and sometimes only apply to a single page.
I'd like to use SVG sprites for them too, but I'm not sure inlining the sprites directly into the HTML is a great idea considering this adds weight to pages that may not use these features. Possible solutions could be:
- to lazy load an external SVG sprite file
- find a way to inline only what's used in a static page (unfortunately,
<Head>does not permit to hoist and deduplicate SVG sprite defs)
@slorber, are these improvements transparent upon Docusaurus upgrade or do they require site owners to adjust anything?
PS: I know they were not released yet.
@felipecrs those are implementation details of theme components and do not change any public API. Unless they swizzled unsafe theme components, site owners have nothing to do when upgrading. Our versioning policy applies as usual, with minor releases aiming to be easy to adopt: https://docusaurus.io/community/release-process
Awesome, thank you.
But how can I customize this icon?
@anonsyn in any case we always use the sprites through an intermediate @theme/Icon/Xyz component.
This means that you can always swizzle them, and make the React component render an inline SVG with JSX, exactly like we did before:
export default function IconExternalLink() {
return (
<svg>
<path d="..."/>
</svg>
);
}
Or you can provide a reference to your own SVG sprite ids, like we do now (more optimized)
If you want to inject new SVG sprites in your page you can use the plugin lifecycle like we do too:
injectHtmlTags() {
return {
preBodyTags: [
{
tagName: 'svg',
attributes: {
xmlns: 'http://www.w3.org/2000/svg',
style: 'display: none;',
},
innerHTML: `<defs>
<symbol id="my-custom-svg-id1" viewBox="0 0 24 24"><path d="..." /></symbol>
<symbol id="my-custom-svg-id2" viewBox="0 0 24 24"><path d="..." /></symbol>
</defs>`;
},
]
};
export default function IconExternalLink() {
<svg>
<use href="my-custom-svg-id1" />
</svg>
);
}