SVG in React/JSX

React and other JSX view libraries allow us to render SVGs and manipulate them based on application state.

What’s this useful for?

While not a feature I reach for every day, it’s useful to know that React supports rendering SVG within JSX. This is because SVG markup can be written directly within HTML, and JSX is no different. These JSX-controlled SVGs are useful for templating SVGs and rendering them with different props for different use cases.

Even something as simple as using this feature for UI icons can save a good amount of asset bundle size by allowing for more granular control than we’re able to achieve with the currentColor CSS technique.

Another use case I’ve encountered is masking images with SVG clipping masks without reproducing the clipping mask in a separate, hardcoded SVG asset file wrapping each image asset. Instead of dozens of SVG files, I was able to use one stateless functional component containing a JSX-controlled SVG and pass the URLs of external image assets via a prop controlling which image file is linked to within each instance of the component. This combined external image files for the actual images with a UI component in the JavaScript bundle.

Example: Template-driven icon component

Now that we’ve explored a couple use cases, let’s take a look at a simple one: controlling an SVG icon with props for color and size.

export const BrowserIcon = ({ color, size }) => (
  <svg
    xmlns="http://www.w3.org/2000/svg"
    version="1.1"
    width={String(size)}
    height={String(size)}
    viewBox="0 0 8 8"
  >
    <path
      fill={color}
      d="M.344 0a.5.5 0 0 0-.344.5v7a.5.5 0 0 0 .5.5h7a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.5-.5h-7a.5.5 0 0 0-.094 0 .5.5 0 0 0-.063 0zm1.156 1c.28 0 .5.22.5.5s-.22.5-.5.5-.5-.22-.5-.5.22-.5.5-.5zm2 0h3c.28 0 .5.22.5.5s-.22.5-.5.5h-3c-.28 0-.5-.22-.5-.5s.22-.5.5-.5zm-2.5 2h6v4h-6v-4z"
    />
  </svg>
);

export const ICON = {
  COLORS: {
    BRAND: '#106fa5',
  },
  SIZES: {
    MED: 24,
  },
};
import { BrowserIcon, ICON } from './icons.jsx';

export default const Example = () => (
  <BrowserIcon color={ICON.COLORS.BRAND} size={ICON.SIZES.MED} />
);

Browser icon from Open Iconic. Copyright © 2014 Waybury, MIT License.