SVGR webpack loader that transforms SVG files into React components during the build process.
npx @tessl/cli install tessl/npm-svgr--webpack@8.1.0@svgr/webpack is a webpack loader that transforms SVG files into React components during the build process. It integrates the SVGR transformation system with webpack's module loading, allowing developers to import SVG files as React components with full TypeScript support and extensive configuration options.
npm install @svgr/webpack --save-devThe package exports a default webpack loader function:
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.svg$/,
use: ['@svgr/webpack'],
},
],
},
};// webpack.config.js - Basic SVG to React component transformation
{
test: /\.svg$/,
use: ['@svgr/webpack'],
}// In your React code
import Star from './star.svg';
const App = () => (
<div>
<Star />
</div>
);@svgr/webpack is built on several key components:
Main webpack loader function that processes SVG files and transforms them into React components.
/**
* SVGR webpack loader function
* @param contents - SVG file contents as string
* @returns void (uses webpack's callback system)
*/
function svgrLoader(
this: webpack.LoaderContext<LoaderOptions>,
contents: string,
): void;
interface LoaderOptions extends Config {
babel?: boolean;
}Complete configuration interface extending SVGR core options with webpack-specific settings.
interface Config {
ref?: boolean;
titleProp?: boolean;
descProp?: boolean;
expandProps?: boolean | 'start' | 'end';
dimensions?: boolean;
icon?: boolean | string | number;
native?: boolean;
svgProps?: {
[key: string]: string;
};
replaceAttrValues?: {
[key: string]: string;
};
runtimeConfig?: boolean;
typescript?: boolean;
prettier?: boolean;
prettierConfig?: PrettierOptions;
svgo?: boolean;
svgoConfig?: SvgoConfig;
configFile?: string;
template?: TransformOptions['template'];
memo?: boolean;
exportType?: 'named' | 'default';
namedExport?: string;
jsxRuntime?: 'classic' | 'classic-preact' | 'automatic';
jsxRuntimeImport?: {
source: string;
namespace?: string;
specifiers?: string[];
defaultSpecifier?: string;
};
jsx?: {
babelConfig?: BabelTransformOptions;
};
}Usage Examples:
// Basic configuration with options
{
test: /\.svg$/,
use: [
{
loader: '@svgr/webpack',
options: {
native: true,
typescript: true,
svgo: false,
},
},
],
}
// With custom SVG props
{
test: /\.svg$/,
use: [
{
loader: '@svgr/webpack',
options: {
svgProps: { role: 'img' },
replaceAttrValues: { '#000': 'currentColor' },
},
},
],
}Seamless integration with other webpack loaders like url-loader for dual-purpose SVG handling.
// Usage with url-loader for both component and URL exports
{
test: /\.svg$/,
use: ['@svgr/webpack', 'url-loader'],
}Usage Example:
// Dual import - both as React component and as URL
import starUrl, { ReactComponent as Star } from './star.svg';
const App = () => (
<div>
<img src={starUrl} alt="star" />
<Star />
</div>
);Disable built-in Babel transformation to use custom Babel configuration.
// Webpack configuration with custom Babel
{
test: /\.svg$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['preact', 'env'],
},
},
{
loader: '@svgr/webpack',
options: { babel: false },
}
],
}Advanced webpack configuration for different file contexts using Rule.issuer.
// Different handling for JavaScript vs CSS imports
[
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
issuer: /\.[jt]sx?$/,
use: ['babel-loader', '@svgr/webpack', 'url-loader'],
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader',
},
]Configuration options specific to the webpack loader.
interface LoaderOptions extends Config {
/** Enable/disable Babel transformation (default: true) */
babel?: boolean;
}Complete SVGR configuration interface with all available options.
interface Config {
ref?: boolean;
titleProp?: boolean;
descProp?: boolean;
expandProps?: boolean | 'start' | 'end';
dimensions?: boolean;
icon?: boolean | string | number;
native?: boolean;
svgProps?: {
[key: string]: string;
};
replaceAttrValues?: {
[key: string]: string;
};
runtimeConfig?: boolean;
typescript?: boolean;
prettier?: boolean;
prettierConfig?: PrettierOptions;
svgo?: boolean;
svgoConfig?: SvgoConfig;
configFile?: string;
template?: TransformOptions['template'];
memo?: boolean;
exportType?: 'named' | 'default';
namedExport?: string;
jsxRuntime?: 'classic' | 'classic-preact' | 'automatic';
jsxRuntimeImport?: {
source: string;
namespace?: string;
specifiers?: string[];
defaultSpecifier?: string;
};
jsx?: {
babelConfig?: BabelTransformOptions;
};
}Processing state information passed to SVGR transformation plugins.
interface State {
filePath?: string;
componentName: string;
caller?: {
name?: string;
previousExport?: string | null;
defaultPlugins?: ConfigPlugin[];
};
}External type definitions from dependencies used in the API.
// From Prettier
interface PrettierOptions {
[key: string]: any;
}
// From SVGO
interface SvgoConfig {
plugins?: string[] | object[];
[key: string]: any;
}
// From @svgr/babel-preset
interface TransformOptions {
template?: (variables: any, context: any) => any;
[key: string]: any;
}
// From @babel/core
interface BabelTransformOptions {
presets?: any[];
plugins?: any[];
[key: string]: any;
}
// From @svgr/core
interface ConfigPlugin {
(code: string, config: Config, state: State): string;
}Webpack-specific type definitions used by the loader.
// Simplified webpack LoaderContext interface (from webpack)
namespace webpack {
interface LoaderContext<TOptions> {
cacheable(): void;
async(): (err?: Error, result?: string) => void;
getOptions(): TOptions;
resourcePath: string;
fs: {
readFile(path: string, callback: (err: Error | null, data?: Buffer) => void): void;
};
}
}The loader automatically detects and handles different export scenarios:
ReactComponent)namedExport optionexportType: 'named'The loader handles errors through webpack's standard callback mechanism:
{
test: /\.svg$/,
use: [
{
loader: '@svgr/webpack',
options: {
typescript: true,
prettier: false,
svgo: true,
svgoConfig: {
plugins: ['preset-default', 'removeViewBox'],
},
},
},
],
}{
test: /\.svg$/,
use: [
{
loader: '@svgr/webpack',
options: {
template: (variables, { tpl }) => {
return tpl`
${variables.imports};
${variables.interfaces};
const ${variables.componentName} = (${variables.props}) => (
${variables.jsx}
);
export default ${variables.componentName};
`;
},
},
},
],
}