Loading SVG icons
Unanswered
Chinese Chongqing Dog posted this in #help-forum
Chinese Chongqing DogOP
I've been using
Using it is pretty straightforward:
The beauty of this loader is that it creates a hidden
bootstrap-icons with svg-sprite-loader. The Bootsrap icons are offered as individual SVG files, icon fonts and as an SVG sprite combined in a single file. I prefer native, semantic and more accessible SVG elements over icon fonts, so I have set up svg-sprite-loader how I want it. I also have a component that renders an icon in an SVG node:export default function Icon({ width = "1em", id }) {
return (
<svg className="bi"
width={width}
height={width}
aria-hidden="true"
focusable="false">
<use href={"#" + id}/>
</svg>
);
}Using it is pretty straightforward:
// heart.js
import Icon from "@/components/icon";
import hearts from "bootstrap-icons/icons/hearts.svg?sprite";
console.dir(hearts);
/*
SpriteSymbol {
id: 'hearts--sprite',
viewBox: '0 0 16 16',
content: '<symbol xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="bi bi-hearts" viewBox="0 0 16 16" id="hearts--sprite">\n' +
' <path fill-rule="evenodd" d="M4.931.481c1.627-1.671 5.692 1.254 0 5.015-5.692-3.76-1.626-6.686 0-5.015Zm6.84 1.794c1.084-1.114 3.795.836 0 3.343-3.795-2.507-1.084-4.457 0-3.343ZM7.84 7.642c2.71-2.786 9.486 2.09 0 8.358-9.487-6.268-2.71-11.144 0-8.358Z" />\n' +
'</symbol>'
}
*/
export default function Heart() {
return <Icon {...hearts} />;
}The beauty of this loader is that it creates a hidden
<svg> node within the <body> and populates it with all the icons as <symbol>s, which then can be referenced from anywhere in the document as done in the Icon component. Only the imported icons are loaded, and only for the current page. It's as good as it can get, right?1 Reply
Chinese Chongqing DogOP
Well, not quite. With multiple icons, it turns into a bit of an inconvenience. Even with
So I tried to reference it directly like
Ultimately, what I'm looking for is a loader that's very similar to
modularizedImports, it becomes tedious and cumbersome to import each of them. Besides, there already is a sprite file provided by bootstrap-icons. So I tried to reference it directly like
<use href="node_modules/bootstrap-icons/bootstrap-icons.svg#hearts"/> and many variations of it; none worked. Then I copied the file to the public directory and set href="/bootstrap-icons.svg#hearts". Obviously it worked, but with a huge penalty; it fetched the whole file containing all icons (around 2K).Ultimately, what I'm looking for is a loader that's very similar to
svg-sprite-loader, but instead of importing each individual icon, I'd only import "bootstrap-icons/bootstrap-icons" into the Icon component and pass id strings to it. It figures out which ones are actually used, trims the sprite down to only those and injects the formed SVG into the document, or sends it to the client.