Joseph Mawa A very passionate open source contributor and technical writer

How to import SVGs into your Next.js applications

5 min read 1565

Importing SVGs Into Next.js Project

Importing SVGs into Next.js apps is a common necessity with our projects today. With the level of support the SVG format has now from a large proportion of libraries and its many benefits regarding scalability, performance, and flexibility, it’s increasingly important for us to know how to use them.

Though our primary focus will be on SVGs, most of the packages we will highlight in this post also apply to other image formats. We will additionally examine some common errors and how to remedy them so you can feel confident when importing SVGs into your Next.js projects.

This article will explore the different methods you can use to import and use SVGs in a Next.js application. Let’s get started.

SVGs in frameworks like Next.js

Scalable Vector Graphics, better known as SVGs, are among the most popular image formats because they are lightweight, scalable, capable of animating, and flexible; allowing you to zoom and resize them without losing image quality.

Despite the popularity of SVG images, their usage is not as straightforward as you might imagine, particularly with frontend frameworks like React and Next.js, which utilize package bundlers.

As a consequence, it’s not uncommon to encounter different errors while attempting to simply import or use an SVG image in a Next.js or React application, which can be frustrating!

There’s no doubt that the benefits of SVGs mean developers aren’t going to stop using them any time soon, so it’s important to understand how to conveniently add them to our projects.

How to import SVGs in Next.js

Next.js has the built-in next/image component for importing and rendering images.

However, you can also render your SVG image inline as a JSX element or import and render it using a third-party package.

We will explore how you can import SVGs in a Next.js application in the following sub-sections.

Embed SVGs using JSX syntax in a React component

One of the easiest ways of using an SVG in a React component is to embed it inline. However, this requires you to convert the SVG elements to JSX syntax. There are several online tools for transforming an SVG image markup to JSX syntax — one such tool is SVGR.

SVGR converts the SVG to JSX syntax and wraps it in a React functional component, like so:

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

N.B., as you can see namespace tags are not supported by default — you can set throwIfNamespace: false to bypass this warning.

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



Svg Namespace Error In Next.js

N.B., again, you will see thatJSX Namespace is disabled by default because React does not support it yet. You can specify jsc.transform.react.throwIfNamespace to false to override default behavior, as noted.

How to load SVGs 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 it can also optimize your images for faster page loading, performance, and visual stability.

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.

You can import and use this like so (see the icon shown 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>
);

Imported Twitter Icon In Browser

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 must be in the images directory in your public directory.

Import SVGs in Next.js 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.


More great articles from LogRocket:


Unlike the built-in next/images 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.

Import SVGs in Next.js using SVGR

As we mentioned previously, 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 basic webpack configuration.

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

    return config
  },
}

You can now import the SVG as a React component and render it in your Next.js application.

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

Load SVGs in Next.js 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.

An ordinary Next.js project setup using create-next-app will include the next/babel preset out of the box.

Since 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.

{
  "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 />; 

Comparing options for importing SVGs in Next.js

Next.js has excellent built-in functionality for loading and rendering several image formats, including SVGs. The next/image component is an extension of the HTML image element and loads images efficiently, while also offering performance optimizations out of the box. In my experience, using next-image results in faster page loads and improved performance.

Therefore, in my view, the built-in next/image component has all the features you need to load and render SVG images efficiently in a Next.js application. It is part of any Next application created using the create-next-app command line tool.

However, you can also explore the third-party options I have highlighted in this article, but you should be aware of the downsides of using such packages in your applications.

These downsides are primarily that they add an extra bundle to your application, which you can avoid by using next/image. You also need to take into account the long-term maintenance of a third-party package in your application and whether it’s feasible to rely on long-term.

Conclusion

I hope this article has demonstrated to you the various methods for importing and using SVGs and images in Next.js applications. Leave a comment in the comments section below if I have missed anything or about your own experiences importing SVGs!

LogRocket: Full visibility into production Next.js apps

Debugging Next applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

LogRocket is like a DVR for web and mobile apps, recording literally everything that happens on your Next.js app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your Next.js apps — .

Joseph Mawa A very passionate open source contributor and technical writer

Leave a Reply