How to import SVGs in Next.js using SVGR

Trying to use SVGs in your Next.js project?

You can throw them into an img tag, but what if you want them as React components?

Enter SVGR - your handy SVG-to-JSX helper!

In this article, we will show you how to get set up so you can use your SVGs just like regular components.

I like this over using an image tag because you can now use props to alter the traits of your SVG, which makes working with them a breeze.

1: Install the Needed Packages

Start with the basics. Get those packages:

npm install --save-dev @svgr/webpack

2: Update the Next.js Config

Head to your next.config.js. Now, tell Webpack/Next.js to use SVGR for SVGs:

module.exports = {
  webpack(config) {
    // Grab the existing rule that handles SVG imports
    const fileLoaderRule = config.module.rules.find((rule) =>
      rule.test?.test?.('.svg'),
    )

    config.module.rules.push(
      // Reapply the existing rule, but only for svg imports ending in ?url
      {
        ...fileLoaderRule,
        test: /\.svg$/i,
        resourceQuery: /url/, // *.svg?url
      },
      // Convert all other *.svg imports to React components
      {
        test: /\.svg$/i,
        issuer: /\.[jt]sx?$/,
        resourceQuery: { not: /url/ }, // exclude if *.svg?url
        use: ['@svgr/webpack'],
      },
    )

    // Modify the file loader rule to ignore *.svg, since we have it handled now.
    fileLoaderRule.exclude = /\.svg$/i

    return config
  },

  // ...other config
}

3: Import SVGs as React Components

The magic moment has arrived!

import User from './icons/user.svg';

function App() {
  // Now we just get to use it like a component 👀
  return <User />;
}

Customize SVGR Options (Optional)

If it's needed, you can pass options to your config to do even more magic. Just update your use: ['@svgr/webpack'] to use: [{ loader: '@svgr/webpack', options: {} }]

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

    config.module.rules.push(
    url
      {
        ...fileLoaderRule,
        test: /\.svg$/i,
        resourceQuery: /url/, // *.svg?url
      },
      {
        test: /\.svg$/i,
        issuer: /\.[jt]sx?$/,
        resourceQuery: { not: /url/ }, // exclude if *.svg?url
        // Add options to "use"
        use: [{
          loader: '@svgr/webpack',
          options: {
          // SVGR options here
          // For example: icon: true
          },
        }],
      },
    )
    fileLoaderRule.exclude = /\.svg$/i

    return config
  },
}

You can check out all of the options here.

Tip

SVGR has a online tool to visualize your SVG-to-JSX transformation. You can try it out here.

Happy coding! 🚀

SvgNextjs
Avatar for Niall Maher

Written by Niall Maher

Founder of Codú - The web developer community! I've worked in nearly every corner of technology businesses; Lead Developer, Software Architect, Product Manager, CTO and now happily a Founder.

Loading

Fetching comments

Hey! 👋

Got something to say?

or to leave a comment.