A Turbopack loader for importing SVG as optimized data URI with dimensions
npm install turbopack-inline-svg-loader

A Turbopack loader for importing SVGs as optimized data URIs with dimensions. The imported object has the same shape as external image ({ src, width, height }) and can be passed directly to the Next.js component.
``ts
import myIcon from './icon.svg';
return
/*
myIcon is an object like:
{
src: 'data:image/svg+xml,...',
width: 32,
height: 32,
}
*/
`
Inlining small SVGs is beneficial because it eliminates additional HTTP requests, resulting in faster page loads and instant rendering. The slight increase in JavaScript bundle size is usually outweighed by the overall performance gains.
Check out this article.
Install via any package manager:
`shNPM
npm i -D turbopack-inline-svg-loader
Configuration
Add the loader configuration to
next.config.js.
Since Next.js v16, you can conditionally apply a loader only to SVGs smaller than a given size:`ts
const nextConfig = {
turbopack: {
rules: {
'*.svg': {
loaders: ['turbopack-inline-svg-loader'],
condition: {
content: /^[\s\S]{0,4000}$/, // <-- Inline SVGs smaller than ~4Kb (since Next.js v16)
},
as: '*.js',
},
},
},
// ...
};
`Usage
Statically import an SVG file and pass it to the
component:`tsx
import Image from 'next/image';
import myIcon from './icon.svg';export default function Page() {
return ;
}
`$3
You can change the image size via the CSS
style prop or className:`tsx
// Set size via style
return ;// Set size with Tailwind
return ;
`$3
For monochrome icons, you can change the color using the CSS mask technique. To achieve this, create a helper component
Icon.tsx that renders the SVG as a mask:`tsx
/**
* A component for rendering monochrome SVG icons using the current text color.
*/
import { type ComponentProps } from 'react';
import { type StaticImageData } from 'next/image';type IconProps = Omit, 'src'> & {
src: StaticImageData;
};
const EMPTY_SVG =
data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'/%3E;export default function Icon({ src, width, height, style, ...props }: IconProps) {
return (
width={width ?? src.width}
height={height ?? src.height}
src={EMPTY_SVG}
style={{
...style,
backgroundColor:
currentcolor,
mask: url("${src.src}") no-repeat center / contain,
}}
{...props}
/>
);
}
`Now you can render colored icons:
`tsx
import Icon from './Icon';
import myIcon from './icon.svg';// Set color with style
return ;
// Set color with Tailwind
return ;
`TypeScript
By default, Next.js imports
.svg assets as the any type to avoid conflicts with SVGR. To make .svg imports behave like other images ({ src, width, height }), create the following svg.d.ts file in the project root:`ts
declare module '*.svg' {
const content: import('next/image').StaticImageData;
export default content;
}
`and add it to
tsconfig.json before next-env.d.ts:`diff
"include": [
+ "svg.d.ts",
"next-env.d.ts",
...
],
`Now your SVG imports will be resolved as
{ src, width, height }`.A short background article How I arrived at this package.
Some other resources to dive deep into the rabbit hole of SVGs:
- A guide to using SVGs in React
- Breaking Up with SVG-in-JS
- Introducing @svg-use
Feel free to share your feedback and suggestions in the issues.