How to import SVGs into your Next.js apps: A 2025 guide

SVGs are everywhere — icons, logos, animated illustrations, even subtle UI flourishes. But integrating them into a modern Next.js (v14+) project isn’t always straightforward. Should you import them as components? Drop them in /public? What about performance, maintainability, or styling?

How To Import SVGs Into Your Next.js Apps

This guide cuts through the confusion with updated 2025 guidance on the four most common SVG methods, including fresh examples, decision rules, and specific help for App Router and TypeScript users.

Whether you’re shipping a design system or just trying to avoid a “broken image” in production, we’ve got you covered.

Editor’s note: This post was last updated on June 2, 2025. This update adds a Quickstart section, simplified code examples, a method decision guide, App Router clarifications, SVGR config updates for Next.js 14+, and a new troubleshooting table.

Quickstart: Importing SVGs in Next.js

Need to render an SVG right now? Here’s a cheat sheet of the most common methods:

Use case Method Code snippet
Inline SVG components SVGR import Icon from './icon.svg'
Static decorative images /public folder + <img> <img src="/logo.svg" alt="Logo" />
Optimized images (incl. SVG) Next.js <Image /> <Image src="/logo.svg" alt="Logo" width={100} height={100} />
Custom inline SVG markup Paste SVG JSX inline  Direct JSX copy/paste inside your component

Why SVGs?

SVGs are among the most popular image formats on the web today. In contrast to their raster image counterparts, vector images offer numerous benefits:

  • Lightweight — Vector graphics take less storage and memory than bitmap images
  • Animatable — Animate them with modern CSS or JavaScript
  • Scalable — They’re resolution-independent, so they scale beautifully on all screens
  • Accessible — SVGs are XML-based, so you can embed text and ARIA roles directly
  • SEO-friendly — Search engines can crawl and index SVG markup

With the above benefits, you must understand how to add them to your projects.

How to import SVGs in Next.js

Vercel, the company behind Next.js, provides a complete platform and a suite of software packages within its ecosystem for you to build and host full-stack applications using Next.js. For any problem you encounter while using Next.js, you will almost always find a solution within the Next.js ecosystem.

Every standard Next.js project comes with a built-in next/image component to work with images. You can use the next/image component for bitmap and vector images. Therefore, when using SVGs or other image formats in a Next.js application, the built-in next/image component will almost always be your first choice.

Next.js (especially v13+ and v14+) gives you several options for working with SVGs — depending on your performance needs and how much control you need over styling and interaction.

Below are four core methods you can use, each with its pros and cons.

Inline SVG in JSX

Embedding an SVG directly in your JSX gives you maximum control. You can style individual parts, apply animations, and even bind interactivity.

But first, convert the raw SVG to JSX format. Tools like SVGR make this easy. SVGR converts the SVG to JSX syntax and wraps it in a React functional component, like this:

const TwitterIcon = ({ props }) => (
  <svg xmlns="http://www.w3.org/2000/svg" width={48} height={48} {...props}>
    <linearGradient
      id="a"
      x1={10.341}
      x2={40.798}
      y1={8.312}
      y2={38.769}
      gradientUnits="userSpaceOnUse"
    >
      <stop offset={0} stopColor="#2aa4f4" />
      <stop offset={1} stopColor="#007ad9" />
    </linearGradient>
    <path
      fill="url(#a)"
      d="M46.105 ..."
    />
  </svg>
)

You may encounter the following error if you don’t convert your SVG to JSX syntax before embedding it in a React component, so always be sure to use a tool like SVGR:

SVG Namespace Error In React

You may also get the error below in Next.js instead of the above error:

SVG Namespace Error In Next.js

Using the next/image component

The next/image component is the de facto component for loading and rendering images — including SVGs — in Next.js. This component efficiently loads and renders images and can optimize your images for faster page loading, performance, and visual stability. It is an extension of the HTML image element.

If you have set up a Next.js application using the Create Next App command line tool, the next/image component should be available for your application. With local SVG images, you can import and use the next/image component as in the example below:

import Image from 'next/image';
import twitterIcon from "../../public/images/twitter-icon.svg";

const App = () => (
  <div>
    <Image
      priority
      src={twitterIcon}
      alt="Follow us on Twitter"
    />
  </div>
);

You don’t need to specify the width and height props because Next.js will determine their values out of the box. On the other hand, for remote images, the src property should be an absolute or relative URL string. You should set the height and width properties like in the example below:

import Image from 'next/image';

const App = () => (
  <div>
    <Image
      priority
      src="/images/twitter-icon.svg"
      height={32}
      width={32}
      alt="Follow us on Twitter"
    />
  </div>
);

As you use the next/image component, be aware that Next.js serves static assets, such as images, from a public directory in your project’s root directory. Therefore, in the example above, the twitter-icon.svg file must be in the images directory in your public directory.

Next.js will import the icon and render it in the browser like the image below:

Twitter Icon In Browser For The Next.js App

You can pass several props to the next/image component. Check the next/image component documentation for a complete list of the required and optional props. In this section, our focus is on using the next/image component to import and render SVGs in a Next.js application.

Using the next-images package

The next-images package is a third-party package for importing images in Next. You can use it instead of the built-in next/image component described above. With next-images, you can load images from your local machine or CDN. In addition, you can also use it to embed images with small bundle sizes in Base64 encoding and cache images by adding a content hash to image names.

Like any other npm package, install next-images from the npm package registry using the following command:

# npm
npm install next-images

# yarn
yarn add next-images

After installation, create a next.config.js file at the root of your project directory and add the following basic configuration:

const withImages = require('next-images');
module.exports = withImages(); 

After adding the necessary configuration to the next.config.js file, as described above, you can import the SVG into your component and render it, as shown here:

import twitterIcon from "./twitter-icon.svg";

const App = () => <img src={twitterIcon} alt="Follow us on Twitter" />;

When using the next-images package, you can load images from a file in your project directory or a CDN. Unlike the built-in next/image component and other third-party packages, the next-images package doesn’t support image optimization techniques such as compression and resizing out-of-the-box.

With modern versions of Next.js, you don’t need this third-party package. The built-in next/image component has all the features you need to import SVGs and other image formats. Nevertheless, this package may still be useful if your project uses older Next.js versions.

Import as React component with SVGR

As previously mentioned, SVGR is a third-party package for converting an SVG image to a React component. Several popular React project template creators, like Create React App, actually use SVGR under the hood. Install it as a development dependency to start importing SVGs as React components in your Next.js application:

# npm
npm install --save-dev @svgr/webpack

# yarn 
yarn add --dev @svgr/webpack

After installation, create a next.config.js file at the root of your project directory and add the following webpack configuration:

module.exports = {
  webpack(config) {
    const fileLoaderRule = config.module.rules.find((rule) =>
      rule.test?.test?.(".svg")
    );

    config.module.rules.push(
      {
        ...fileLoaderRule,
        test: /.svg$/i,
        resourceQuery: /url/,
      },

      {
        test: /.svg$/i,
        issuer: fileLoaderRule.issuer,
        resourceQuery: { not: [...fileLoaderRule.resourceQuery.not, /url/] },
        use: ["@svgr/webpack"],
      }
    );

    fileLoaderRule.exclude = /.svg$/i;

    return config;
  },
};

You can now import the SVG as a React component and render it in your Next.js application. Here’s how that should look:

import TwitterIcon from "./twitter-icon.svg";
const Example = () => <TwitterIcon />; 

Using babel-plugin-inline-react-svg

Instead of importing SVG images using the SVGR package as in the previous sub-section, it is also possible to use a Babel plugin to achieve the same effect.

To start using babel-plugin-inline-react-svg, install it as a development dependency from the npm package registry using this command:

npm i -D babel-plugin-inline-react-svg

After installation, create a .babelrc or babel.config.json configuration file at the root of your project directory. You can copy and paste the code from the block below into it. If you have a Babel configuration file, Next.js will treat it as the ultimate source of truth.

You need to be aware that adding a custom Babel config will opt you out of using the Next.js compiler. However, the compiler is required for you to use the next/font module in your project. Therefore, to use babel-plugin-inline-react-svg, you have to stop using the next/font module.

An ordinary Next.js project setup using Create Next App will include the built-in next/babel preset. Because Next.js will treat a .babelrc or babel.config.json file at the root of your project directory as the primary source of information, it must have everything you will need — including those that Next.js needs. Refer to the following code:

{
  "presets": ["next/babel"],
  "plugins": ["inline-react-svg"]
}

After you’ve done this, you can import SVG images as React components and render them in your Next.js application:

import TwitterIcon from "./twitter-icon.svg";
const Example = () => <TwitterIcon />; 

How to use SVGs with the img tag

The simplest way of using SVGs in a React or Next application is the img tag, as in a regular HTML file. However, as hinted above, Next.js looks for static assets like images in the public directory in your application’s root directory. Be sure all the images you want to bundle with your application are in the public directory at build time.

You can also host the image on a different server and reference it using the image URL. The usage of the <img/> tag in Next.js is similar to the usage of the HTML img element. The src and alt attributes are required, as shown below:

<img src="/twitter-icon.svg" alt="Follow us on Twitter" />

Implementing SVG favicons in Next.js

You need to implement favicons when building websites and web applications. They help users easily identify your brand among open browser tabs, browsing history, bookmarks, and search engine results.

A typical favicon is an ICO image file. However, you can also use other image formats like SVG, PNG, and JPG. Next.js supports favicons out of the box.

If your Next.js project is using the Pages Router, you need to place the SVG icon in the public directory and add it to your head element using the built-in <Head /> component like so:

export default function Home() {
  return (
    <>
      <Head>
        <link rel="icon" href="/icon.svg" type="image/svg+xml" />
      </Head>
    </>
  );
}

If your project uses the App Router and your favicon is in ICO format, you need to name it favicon.ico and place it in the app directory. Next.js will process the favicon and add the relevant HTML tags to your document’s <head> element out of the box. For this to work, the favicon.ico file should be within the app directory, not in a sub-directory.

Similarly, if your favicon is an SVG or other image formats like JPG and PNG, you need to name it icon.(svg|jpg|png) and place it in the app directory. Next.js will load and process the icon and add the necessary HTML tags to the document’s <head> element. Next.js will use the image file to correctly infer the icon’s MIME type and size.

As an example, if your SVG icon has a width and height of 96px, Next.js will generate a <link> element like so:

<link rel="icon" href="/icon.svg?icon.65eec5af.svg" sizes="96x96" type="image/svg+xml">

Browsers usually cache static assets such as favicons. It is not uncommon for your page to display an old favicon after adding a new one. Therefore, you may need to clear the cache and reload the page for the browser to load the new favicon.

Decision guide: Which SVG import method should you use?

Use this quick decision tree to pick the best method:

  • Do you need to style the SVG using className, pass props, or reuse it like a React component? → Use SVGR.
  • Is the SVG purely decorative or static (like a logo)?
    • Need zero setup and a fast way to display it? → Use /public + <img>.
    • Want performance benefits like lazy loading or built-in sizing? → Use <Image />.
  • Are you animating the SVG, changing parts of it dynamically, or using logic with it? → Use Inline JSX.

Still not sure? Start with SVGR for anything interactive or reusable, and fall back to <img> or <Image /> for quick wins.

Using SVGs with Next.js 13+ App Router: What’s new?

  • Server components — SVG imports in server components require careful handling; inline SVGs or static /public folder usage are safest

  • Dynamic imports — When importing SVGs as React components in client components, use dynamic() with ssr: false if you encounter hydration errors

  • No built-in SVGR support yet — You still need to configure SVGR in next.config.js manually

Troubleshooting common SVG import issues

❌ SVG not rendering in Next.js?

  • Check the path — Is your SVG inside the /public folder or properly imported as a module?
  • Case matters — File paths are case-sensitive on some systems (e.g., Linux).
  • Using next/image? — Make sure you define width and height — required for SVG rendering.

⚠ “You may need an appropriate loader” error?

Cause: Missing SVGR config in next.config.js.

Fix:

module.exports = {
webpack(config) {
config.module.rules.push({
test: /.svg$/i,
issuer: /.[jt]sx?$/,
use: ['@svgr/webpack'],
});
return config;
},
};

⚠ MIME type error: “Refused to execute as script”?

Cause: Trying to import an SVG without a proper loader.

Fix: Use a static <img src="/your.svg" /> instead, or set up SVGR for inline use.

⚠ SVG won’t style with Tailwind/CSS?

Cause: Styling may not apply to inline SVG if it’s embedded via <img>.

Fix: Use SVGR to inline the SVG as a React component — this lets Tailwind or CSS classes apply.

⚠ Hydration mismatch error?

Cause: Mixing server/client components when importing SVGs.

Fix: Import the SVG only in Client Components, or use dynamic() with ssr: false:

import dynamic from 'next/dynamic';

const Logo = dynamic(() => import('./logo.svg'), { ssr: false });

Conclusion

I hope this article helped clarify the different ways to import and use SVGs and images in Next.js applications. The built-in next/image component offers a powerful, optimized solution for most use cases.

If your project has more specific needs, the third-party packages we covered can offer added flexibility — but be sure to weigh their maintenance status, security, and licenses before integrating them.

Have tips, questions, or your own experience with SVGs in Next.js? Drop a comment below — I’d love to hear it!

The post How to import SVGs into your Next.js apps: A 2025 guide appeared first on LogRocket Blog.

 

This post first appeared on Read More