I'm developing a website using Next JS and I want to display some SVG icons that I stored using Sanity. How do I display the SVG that I get from the Sanity CDN if I want to be able to dynamically change its fill color (e.g. change the color when the icon is hovered)? Or is this not possible?
Here's a summary of the my code, just to show you what I'm trying to do:
const [icon, setIcon] = useState('');
useEffect(() => {
const query = '*[_type == "socials"]'
client.fetch(query)
.then((data) => {
setIcon(urlFor(data.icon).width(24).url());
});
}, []);
<NextImage
useSkeleton
src={icon}
width='24'
height='24'
alt='name'
/>
Note: NextImage component above is basically a next/image component with a skeleton loading effect added to it.
With the code above, I was able to display the SVGs successfully, so no problem there. But, I can't seem to be able to add a hover effect to dynamically change the color of the displayed SVG. That's what I hope to get answers on.
Here's the displayed SVG icons:
I want to be able to change the color of those icons programmatically without having to change the SVGs that I already uploaded to Sanity.
CodePudding user response:
You can only style SVGs if they are inlined into the HTML, not through an <img>
tag or external URL.
However, it might be possible to fetch the SVG markup from the image URL and inline it into the HTML. You'll need to get the original SVG URL (so you can't resize it with the .width()
function).
Once you have the SVG URL (ends with .svg, going to the URL presents the SVG markup), you can fetch the data with fetch()
or your preferred method, then use dangerouslySetInnerHTML
to embed the returned SVG markup into a <div>
. (Make sure you trust where the images are coming from, or you'll need to sanitize it.)
Styling the SVG will depend on how you're managing styles in your application and also the specific SVG, but you could do something like:
/* target svgs inside a div with class "inline-svg" */
div.inline-svg svg {
color: black;
width: 24px;
height: 24px;
}
div.inline-svg:hover svg {
color: red;
}
This will only work if your SVG has fill="currentColor"
or stroke="currentColor"
depending on how it's structured.