Reputation: 568
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?
Upvotes: 16
Views: 52191
Reputation: 47
The Code:
webpack: (config, options) => {
config.module.rules.push({
test: /\.svg$/,
use: [
options.defaultLoaders.babel,
{
loader: "@svgr/webpack",
options: {
icon: true,
},
},
],
});
return config;
},
Upvotes: 0
Reputation: 929
I got SVGs working with this next.js config.
next.config.js
module.exports = {
webpack(config) {
config.module.rules.push({
test: /\.svg$/i,
issuer: /\.[jt]sx?$/,
use: ['@svgr/webpack'],
})
return config
},
}
Upvotes: 3
Reputation: 238
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 -
.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.
Upvotes: 9
Reputation: 4264
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>
);
}
}
Upvotes: 28
Reputation: 963
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 />
Upvotes: 11