6
votes

I am trying to import an SVG image from file into a Next.js component.

In the assets folder I have google.svg (icon):

<svg className="svgIcon-use" width="25" height="37" viewBox="0 0 25 25">
    <g fill="none" fillRule="evenodd">
      <path
        d="M20.66 12.693c0-.603-.054-1.182-.155-1.738H12.5v3.287h4.575a3.91 3.91 0 0 1-1.697 2.566v2.133h2.747c1.608-1.48 2.535-3.65 2.535-6.24z"
        fill="#4285F4"
      />
      <path
        d="M12.5 21c2.295 0 4.22-.76 5.625-2.06l-2.747-2.132c-.76.51-1.734.81-2.878.81-2.214 0-4.088-1.494-4.756-3.503h-2.84v2.202A8.498 8.498 0 0 0 12.5 21z"
        fill="#34A853"
      />
      <path
        d="M7.744 14.115c-.17-.51-.267-1.055-.267-1.615s.097-1.105.267-1.615V8.683h-2.84A8.488 8.488 0 0 0 4 12.5c0 1.372.328 2.67.904 3.817l2.84-2.202z"
        fill="#FBBC05"
      />
      <path
        d="M12.5 7.38c1.248 0 2.368.43 3.25 1.272l2.437-2.438C16.715 4.842 14.79 4 12.5 4a8.497 8.497 0 0 0-7.596 4.683l2.84 2.202c.668-2.01 2.542-3.504 4.756-3.504z"
        fill="#EA4335"
      />
    </g>
  </svg>

I need to import that SVG inside of this inside of the Next.js component:

import googleLogo from '../assets/google.svg';

class Login extends React.Component {
  render() {
    return (
      <LoginLayout title="Login Page">
        <div>
          <Link href="/auth/google">
            <a className="button">
              <div>
                <span className="svgIcon t-popup-svg">
                  {googleLogo}   // <---- import here icon
                </span>
                
              </div>
            </a>
          </Link>
        </div>
      </LoginLayout>
    );
  }
}

I installed this package: https://www.npmjs.com/package/next-images

and set configuration based on that documentation in next.config.js:

const withCSS = require('@zeit/next-css');
const withSass = require('@zeit/next-sass');
const withImages = require('next-images');

module.exports = withCSS(
  withSass({
    webpack: (config) => config,
    distDir: '../_next'
  }),
  withImages({
    exclude: path.resolve(__dirname, 'client/assets/svg'),
    webpack(config, options) {
      return config;
    }
  })
);

Why my import of SVG does not work?

4
Why would you exclude the svg fodler you are trying to work with in your webpack config?GifCo
That is mistake, I didn't thing of that when i copy paste code.Mark James
After trying some configurations from the internet, I found it easy to pass the location of the svg image, to the img tag or <Image /> imported from 'next/image'.Ali Baghban

4 Answers

13
votes

Another approach would be to make a component for your svg. I like this approach because I can easily pass in props for width, height color etc if required on the svg.

//GoogleLogo.js
import React from "react";
export default function GoogleLogo() {
  return (
    <svg className="svgIcon-use" width="25" height="37" viewBox="0 0 25 25">
      <g fill="none" fillRule="evenodd">
        <path
          d="M20.66 12.693c0-.603-.054-1.182-.155-1.738H12.5v3.287h4.575a3.91 3.91 0 0 1-1.697 2.566v2.133h2.747c1.608-1.48 2.535-3.65 2.535-6.24z"
          fill="#4285F4"
        />
        <path
          d="M12.5 21c2.295 0 4.22-.76 5.625-2.06l-2.747-2.132c-.76.51-1.734.81-2.878.81-2.214 0-4.088-1.494-4.756-3.503h-2.84v2.202A8.498 8.498 0 0 0 12.5 21z"
          fill="#34A853"
        />
        <path
          d="M7.744 14.115c-.17-.51-.267-1.055-.267-1.615s.097-1.105.267-1.615V8.683h-2.84A8.488 8.488 0 0 0 4 12.5c0 1.372.328 2.67.904 3.817l2.84-2.202z"
          fill="#FBBC05"
        />
        <path
          d="M12.5 7.38c1.248 0 2.368.43 3.25 1.272l2.437-2.438C16.715 4.842 14.79 4 12.5 4a8.497 8.497 0 0 0-7.596 4.683l2.84 2.202c.668-2.01 2.542-3.504 4.756-3.504z"
          fill="#EA4335"
        />
      </g>
    </svg>
  );
}

and in your file from above.

  import GoogleLogo from "./GoogleLogo";

  class Login extends React.Component {
    render() {
      return (
        <LoginLayout title="Login Page">
          <div>
            <Link href="/auth/google">
              <a className="button">
                <div>
                  <span className="svgIcon t-popup-svg">
                    <GoogleLogo />
                  </span>

                </div>
              </a>
            </Link>
          </div>
        </LoginLayout>
      );
    }
  }
8
votes

I've recently added this myself. I followed the example on the Next.js repo.

https://github.com/zeit/next.js/tree/master/examples/svg-components

There's a couple of steps -

1) You need to install the following dependency :

  • babel-plugin-inline-react-svg

2) Inside your .babelrc you need to add the plugin babel-plugin-inline-react-svg

  "plugins": [
    "inline-react-svg",
  ]

You should then be able to import your SVG's into your components. Here's a gist of something similar I used it for.

https://gist.github.com/iamchristough/493c60112770058566d559e6860dc4c9

Note - you need to declare it as its own component <GoogleLogo /> if you just did {GoogleLogo} it will error. Also there is an issue with how babel transforms the SVG so any changes inside the SVG file won't appear. You need to rename the file in order for the bundler to see a change.

Hope this helps.

3
votes

You can use @svgr/webpack plugin to convert svg imports to react component.

This will allow you to do the following:

import Icon from './icon.svg';

<Icon />
1
votes

You can transform the svg into component with svgr https://github.com/gregberge/svgr