Scalable Vector Graphics (SVG) are an XML-based vector image format for two-dimensional graphics with support for interactivity and animation. Unlike raster images (like JPG, PNG), SVGs are resolution-independent, meaning they look crisp at any zoom level without pixelation, making them ideal for icons, logos, illustrations, and charts in web applications.
Why Use SVG with React?
1. Scalability: SVGs scale perfectly across different screen sizes and resolutions, ensuring a consistent look and feel without loss of quality.
2. Small File Sizes: For simple graphics, SVGs are often much smaller than their raster counterparts, leading to faster load times.
3. Styling & Interactivity: SVG elements are part of the DOM, allowing them to be easily styled with CSS (colors, strokes, fills, animations) and manipulated with JavaScript.
4. Accessibility: SVG allows for semantic elements (`<title>`, `<desc>`) and ARIA attributes, improving accessibility for screen readers.
5. Performance: No extra HTTP requests if embedded inline, and can be optimized to reduce file size.
Methods to Use SVG in React:
There are several ways to integrate SVGs into your React applications, each with its own advantages and use cases:
# 1. Inline SVG
Directly embed the SVG XML code within your JSX. This gives you maximum control and allows for dynamic manipulation using React's state and props.
Pros:
* Full control over SVG attributes and styles via props or state.
* No extra HTTP requests, which can improve performance for small, frequently used SVGs.
* Easy to apply dynamic styles and animations using CSS-in-JS or inline styles.
* Good for small, unique icons that might change based on component logic.
Cons:
* Can make your JSX verbose and harder to read if the SVG code is large.
* Requires careful handling of SVG attributes (e.g., `stroke-width` becomes `strokeWidth` in JSX due to camelCase convention).
* Can increase bundle size if the same SVG is repeated across many components.
Example:
```jsx
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path d="M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2Z"></path>
</svg>
```
# 2. Importing SVG as a React Component
Modern build tools like Create React App, Next.js, or custom Webpack configurations (using `@svgr/webpack`) allow you to import SVG files directly as React components. This is often the most recommended approach for reusable icons.
Pros:
* Treats SVGs as first-class React components, promoting reusability.
* Clean JSX syntax: `<MyIcon size={32} color="blue" />`.
* Allows passing props to control SVG attributes (e.g., `fill`, `stroke`, `width`, `height`).
* Benefits from tree-shaking, only bundling SVGs that are actually used.
* SVGs are external files, keeping JSX clean.
Cons:
* Requires specific bundler configuration (though common in modern frameworks).
Example (assuming a configured build tool):
```jsx
import { ReactComponent as StarIcon } from './StarIcon.svg';
// In your component:
<StarIcon width={32} height={32} fill="gold" />
```
# 3. Using `<img>` Tag
You can use an `<img>` tag to embed an SVG file, just like any other image format.
Pros:
* Simplest method for displaying an SVG.
* Browser caching works efficiently.
Cons:
* Limited styling: You can only control the overall size and position of the SVG, not its internal elements (like `path` fill colors) via CSS or JavaScript from the parent component.
* No access to the SVG's internal DOM for manipulation or interactivity.
* Accessibility relies solely on the `alt` attribute.
Example:
```jsx
import myIcon from './my-icon.svg';
<img src={myIcon} alt="A descriptive alt text for the icon" />
```
# 4. Using SVG as a CSS Background Image
SVGs can also be used as background images in CSS.
Pros:
* Good for decorative elements or patterns.
* Doesn't clutter the HTML.
Cons:
* Similar limitations to the `<img>` tag regarding styling and manipulation of internal elements.
* Less flexible for interactive or dynamic content.
Example:
```css
.my-div {
background-image: url('./my-icon.svg');
background-size: contain;
width: 50px;
height: 50px;
}
```
Styling SVG Elements
You can style SVG elements using:
* Inline styles: `style={{ fill: 'red', strokeWidth: 2 }}`
* CSS classes: Assign classes to SVG elements and define styles in a CSS stylesheet.
* CSS variables: Define custom properties (CSS variables) to dynamically change SVG colors or other attributes.
* Props: When importing SVGs as components, pass `fill`, `stroke`, `width`, `height`, etc., as props to the component.
Accessibility (A11y)
For meaningful SVGs, ensure they are accessible:
* Use `<title>` and `<desc>` elements inside the `<svg>` tag to provide a human-readable title and description.
* Use `aria-labelledby` to link the SVG to its title and description.
* Set `role="img"` for decorative SVGs that are semantically images.
* For `<img>` tags, always provide a meaningful `alt` attribute.
By choosing the appropriate method, you can effectively leverage the power of SVG in your React applications, creating visually stunning, scalable, and performant user interfaces.
Example Code
import React from 'react';
// For inline SVG example:
const InlineHeartIcon = ({ size = 24, color = 'red' }) => {
return (
<svg
width={size}
height={size}
viewBox="0 0 24 24"
fill="none"
stroke={color}
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
aria-labelledby="inline-heart-title inline-heart-desc"
role="img"
>
<title id="inline-heart-title">Inline Heart Icon</title>
<desc id="inline-heart-desc">A heart icon demonstrating inline SVG usage.</desc>
<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
</svg>
);
};
// For demonstrating SVG as a component, we'll create a mock component.
// In a real project with a bundler configured for SVGs (like Create React App
// with `@svgr/webpack`), you would typically have a 'StarIcon.svg' file
// and import it like: `import { ReactComponent as StarIcon } from './StarIcon.svg';`
const StarIcon = ({ size = 24, fill = 'orange', stroke = 'currentColor', className = '' }) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={size}
height={size}
viewBox="0 0 24 24"
fill={fill}
stroke={stroke}
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className={className}
aria-labelledby="star-title star-desc"
role="img"
>
<title id="star-title">Star Icon</title>
<desc id="star-desc">A star icon often used for ratings or favorites.</desc>
<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
</svg>
);
};
// Main App component to demonstrate usage
function App() {
return (
<div style={{ padding: '20px', fontFamily: 'Arial, sans-serif' }}>
<h1>Using SVG with React</h1>
<h2>1. Inline SVG Example</h2>
<p>Directly embedding SVG code into your JSX, allowing dynamic props.</p>
<div style={{ display: 'flex', alignItems: 'center', gap: '15px' }}>
<InlineHeartIcon size={30} color="crimson" />
<InlineHeartIcon size={40} color="hotpink" />
<InlineHeartIcon size={50} color="purple" />
</div>
<h2>2. SVG as a React Component Example</h2>
<p>This method treats an SVG file as a reusable React component. (Requires bundler support like <code>@svgr/webpack</code>).</p>
<div style={{ display: 'flex', alignItems: 'center', gap: '15px' }}>
{/* The StarIcon component here is a direct component for demonstration. */}
{/* In a real setup, it would be imported from a .svg file. */}
<StarIcon size={30} fill="gold" stroke="darkgoldenrod" />
<StarIcon size={40} fill="lightskyblue" stroke="deepskyblue" />
<StarIcon size={50} fill="lightgreen" stroke="forestgreen" className="animated-star" />
</div>
<h2 style={{marginTop: '30px'}}>Styling and Accessibility Notes:</h2>
<ul>
<li>Notice how <code>InlineHeartIcon</code> and <code>StarIcon</code> accept <code>size</code>, <code>color</code>/<code>fill</code> props to dynamically change their appearance.</li>
<li>SVG attributes like <code>stroke-width</code> are written in camelCase (<code>strokeWidth</code>) in JSX.</li>
<li><code><title></code> and <code><desc></code> tags along with <code>aria-labelledby</code> and <code>role="img"</code> are included for accessibility.</li>
<li>A CSS class (<code>.animated-star</code>) is applied to one of the <code>StarIcon</code> instances to show CSS styling and hover effects.</li>
</ul>
{/* Inline style block for the example to keep it self-contained */}
<style>
{`
.animated-star {
transition: transform 0.3s ease-in-out, fill 0.3s ease-in-out;
}
.animated-star:hover {
transform: scale(1.2) rotate(15deg);
fill: #ffcc00; /* Change fill on hover */
}
`}
</style>
</div>
);
}
export default App;








Using SVG with React