Reputation: 777
It doesn't seem to be possible so far to control the SVG elements that are stored in a separate file. I thought maybe with WebPack and npm modules it should be possible yet can't find a simple or convenient solution. Is it possible to import element like this?
import icon from "./icons/user.svg"
<icon fill="red" />
I don't understand why it is so hard to work with SVG here, or why can't I find enough information on the topic. Maybe I am doing this wrong? Are there better ways to manage a lot of icons for a React website? I need will be using quite a few, like social networks stuff and similar.
Upvotes: 4
Views: 15428
Reputation: 7382
If you use Create React App, then the easiest solution is to import SVG as a React component
import { ReactComponent as User } from './icons/user.svg';
const View = () => <User />;
See more in the docs: https://facebook.github.io/create-react-app/docs/adding-images-fonts-and-files#adding-svgs
Upvotes: 4
Reputation: 913
I know I looks a bit struggling, but here is the best solution I could end up with : Use webpack file-loader
to get the url of your svg and use it as a css mask on which you can apply a background color and some sizing options :
const name = 'chevron-up';
const size = 16;
const url = require(`!file-loader!../../../vendor/my-icons/icons/${name}.svg`);
return
<span style={{
height: size,
width: size,
display: 'inline-block',
backgroundColor: backgroundColor || 'black',
WebkitMask: `url('${url}') no-repeat 50% 50% / cover`,
mask: `url('${url}') no-repeat 50% 50% / cover`,
}} />
;
It has a couple compatibility isssues for now, but it is supported by most latest browsers. So I guess we should embrace the future my friend !
https://developer.mozilla.org/fr/docs/Web/CSS/mask
Upvotes: 0
Reputation: 688
Include an external SVG image with four lines of code:
<svg>
<use xlinkHref={'/images/logo.svg#Version-2'}>
</use>
</svg>
In this case the SVG image "logo.svg" will have an ID in it named: "Version-2". The part after the hash "#" maps to an ID in the SVG image that must of course exist.
Upvotes: 2
Reputation: 2884
I would suggest to keep the code simple and treat SVG as a HTML. This way you avoid resizing/stretch/config and host of other SVG/React issues.
Create a generic Icon component,
const Icon = ({ name, children }) => (
<svg className={`icon icon-${name}`}>
{children}
</svg>
)
Create the user Icon component,
const UserIcon = ({ fill }) => (
// fill your inner svg code here, set fill to the correct react node
)
Upvotes: 0
Reputation: 777
This answered my question:
https://github.com/gilbarbara/react-inlinesvg
Embed the CSS in the SVG document
Link to a CSS file in your SVG document
Embed the SVG in your HTML
But there's an alternative that sidesteps these issues: load the SVG with an XHR request and then embed it in the document. That's what this component does.
I decided to use inline-svg for react, but I was also told about another method wrapping SVG into an object. I don't know anything about that as I haven't tried yet, but I'll list it just to fill up the collection:
<object>
<embed src="/static/filename.svg">
</object>
Upvotes: 0