6

In next.config.js - I added config which is needed for using SVG images.

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({
      webpack(config, options) {
        return config;
      }
    })
  )
);

And here is my SVG file, under next folders /client/assets/googleIcon.svg.

Maybe problem is in the SVG file. I don't have experience with SVG, is this SVG correct?

<svg version="1.1" width="100%" height="100%" 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 on the end I am importing this file and tried to show image in the followign ways:

  1. {googleIcon}
  2. <img src={googleIcon} />

When I run the app I receive the following error:

./assets/googleIcon.svg 2:0
Module parse failed: Unexpected token (2:0)
You may need an appropriate loader to handle this file type.
Michel Jung
  • 2,966
  • 6
  • 31
  • 51
Mark James
  • 338
  • 4
  • 15
  • 43

3 Answers3

3

I suggest to wrap your svg in a component, and then use the component:

function Icon () {
  return (
    <svg version="1.1" width="100%" height="100%" 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>
  )
}

ReactDOM.render(<Icon />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app" />

If you really need to load svg as image, you need to configure your webpack.

npm install @svgr/webpack

Then:

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

    return config;
  }
};

See this answer.

soywod
  • 4,377
  • 3
  • 26
  • 47
2

You will need to nest the withImages into withSass function. This is why these functions take config as argument.

If you need to provide each of these arguments, they can be combined into the most nested functions argument.

module.exports = withCSS(
  withSass(
    withImages({
      distDir: '../_next',
      webpack(config, options) {
        return config;
      }
    })
  )
);

Agney
  • 18,522
  • 7
  • 57
  • 75
  • Nice, I fixed that error, do you know maybe Why i am getting error: "Invariant Violation: Invalid tag: data:image/svg+xml;base64" ? – Mark James May 24 '19 at 09:12
  • 1
    @MarkJames Aren't you trying the second method, ``? – Agney May 24 '19 at 09:20
  • I tried and still does not work. Now webpack loader is not problem. Just images is not showed. I am getting that warning messages actualy is not error. – Mark James May 24 '19 at 09:24
  • 1
    It's hard to tell from this, but this warning normally occurs when `base64` image is rendered directly in React, something like `{googleIcon}` can cause it – Agney May 24 '19 at 09:28
2

When I add esModule: false to options it works.

config.module.rules.push({
  test: /\.(eot|woff|woff2|ttf|svg|png|jpg|gif)$/,
  use: {
    loader: 'url-loader',
    options: {
      limit: 100000,
      name: '[name].[ext]',
      esModule: false,
    },
  },
});
Penny Liu
  • 15,447
  • 5
  • 79
  • 98
msefer
  • 331
  • 2
  • 10