React Inlinesvg
react-inlinesvg is a React component and hook designed for loading and rendering SVG files directly inline within your application's DOM. It supports various `src` inputs including local paths, remote URLs, data URIs, and raw SVG strings, offering broad flexibility. The current stable version is 4.3.0. The package maintains an active release cadence, frequently publishing minor updates for bug fixes, dependency upgrades, and new features, such as the `useInlineSVG` hook introduced in v4.3.0. Key differentiators include robust caching mechanisms for remote SVGs (both in-memory and browser cache with `CacheProvider`), server-side rendering (SSR) compatibility, and extensive customization through props like `preProcessor` for SVG content manipulation, `loader` for loading states, and comprehensive error handling callbacks. This enables developers to dynamically style and interact with SVGs, addressing common challenges like external stylesheet coupling and inefficient image requests.
Common errors
-
'SVG' cannot be used as a JSX component. Its instance type 'InlineSVG' is not a valid JSX element. The types returned by 'render()' are incompatible between these types.
cause This TypeScript error typically indicates a version mismatch between `react-inlinesvg`'s types and your installed React/TypeScript versions, or incorrect import of the SVG component.fixEnsure `react-inlinesvg` is up to date and compatible with your React version (check peer dependencies). You might need to add a `resolutions` field in your `package.json` for `@types/react` to enforce a specific version that aligns with your project. -
Error: Failed to fetch SVG: ... Network request failed / CORS policy blocked.
cause Attempting to load a remote SVG from a different origin without proper CORS (Cross-Origin Resource Sharing) headers configured on the SVG's server, or a general network issue.fixEnsure the server hosting the SVG file has appropriate CORS headers (`Access-Control-Allow-Origin`) configured to allow requests from your domain. Verify the URL is correct and accessible. -
Warning: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate.
cause Often related to infinite re-render loops caused by state updates within render or effects without proper dependency arrays, historically tied to the `loader` prop in older `react-inlinesvg` versions.fixUpgrade to `react-inlinesvg@4.3.0` or newer. If the issue persists, review how state is managed in your `loader` component or within `onError`/`onLoad` callbacks to prevent unintended re-renders. -
SVG content not displayed or styles incorrect when using `uniquifyIDs`.
cause Internal SVG references (like `url(#id)`) are not correctly resolving after `uniquifyIDs` processes the SVG, especially if a `<base>` tag is present in your HTML.fixProvide the `baseURL` prop to the `SVG` component. The `baseURL` should be the base URL for resolving relative `url()` references within the SVG, often `window.location.href` or a specific asset path.
Warnings
- breaking The `innerRef` prop on the `SVG` component was renamed to `ref` (standard React ref prop) in version 4.2.0. Direct usage of `innerRef` will no longer work as expected.
- gotcha Versions prior to 4.3.0 could experience an infinite re-render loop when using the `loader` prop, particularly if multiple SVGs loaded simultaneously.
- gotcha When using `uniquifyIDs` for SVG elements (e.g., gradients, masks, clip-paths with `url()` references) and your HTML page utilizes a `<base>` tag, SVG references might break. The `baseURL` prop is essential to correctly prepend to these `url()` references and ensure they resolve properly.
- gotcha Earlier versions, particularly prior to v4.1.8, had issues with Server-Side Rendering (SSR) due to incorrect `canUseDOM` checks, leading to a mismatch between server and client rendered output or SVGs not loading on the server.
Install
-
npm install react-inlinesvg -
yarn add react-inlinesvg -
pnpm add react-inlinesvg
Imports
- SVG
const SVG = require('react-inlinesvg');import SVG from 'react-inlinesvg';
- useInlineSVG
import { useInlineSVG } from 'react-inlinesvg'; - CacheProvider
import { CacheProvider } from 'react-inlinesvg';import CacheProvider from 'react-inlinesvg/provider';
Quickstart
import React, { useState } from 'react';
import SVG from 'react-inlinesvg';
import CacheProvider from 'react-inlinesvg/provider';
const MySVGIcon = ({ src, title, description, width = 64, height = 64 }) => {
const [error, setError] = useState(null);
const [loading, setLoading] = useState(true);
return (
<SVG
src={src}
width={width}
height={height}
title={title}
description={description}
cacheRequests={true}
loader={loading && <div style={{ width, height, background: '#eee', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>Loading...</div>}
onError={(err) => {
console.error('SVG loading error:', err);
setError(err);
setLoading(false);
}}
onLoad={(loadedSrc, isCached) => {
console.log(`SVG loaded: ${loadedSrc} (cached: ${isCached})`);
setLoading(false);
setError(null);
}}
preProcessor={(code) => code.replace(/fill="(?!none).*?"/g, 'fill="currentColor"')}
// Any additional props are passed to the SVG element
style={{ color: '#007bff' }} // Example: Change SVG fill via currentColor
>
{error ? <div style={{ width, height, border: '1px solid red', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'red' }}>Error loading SVG</div> : null}
</SVG>
);
};
export default function App() {
const remoteSvgSrc = 'https://cdn.svglogos.dev/logos/react.svg';
const localSvgPath = '/my-local-icon.svg'; // Ensure this file exists in your public directory
// In a real app, ensure your build system handles local SVG paths appropriately
// For CRA, localSvgPath can be a direct path to public/, or import from assets folder.
// For illustration purposes, assuming it's accessible.
return (
<CacheProvider>
<div style={{ fontFamily: 'sans-serif', padding: '20px' }}>
<h1>react-inlinesvg Demo</h1>
<p>Remote SVG (React logo):</p>
<MySVGIcon src={remoteSvgSrc} title="React Logo" width={80} height="auto" />
<p style={{ marginTop: '20px' }}>Example of a missing local SVG (will show error fallback):</p>
<MySVGIcon src={localSvgPath} title="Local Icon" width={50} height={50} />
<p style={{ marginTop: '20px' }}>Using useInlineSVG hook (from v4.3.0):</p>
<InlineSVGHookDemo />
</div>
</CacheProvider>
);
}
// Example using the useInlineSVG hook
function InlineSVGHookDemo() {
const { SVG: SvgElement, loading, error } = useInlineSVG('https://cdn.svglogos.dev/logos/typescript.svg');
if (loading) return <div style={{ width: 80, height: 80, background: '#eee', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>Hook Loading...</div>;
if (error) return <div style={{ width: 80, height: 80, border: '1px solid red', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'red' }}>Hook Error: {error.message}</div>;
return SvgElement ? <SvgElement title="TypeScript Logo" width={80} height={80} style={{ color: '#007ACC' }} /> : null;
}