I downloaded the Vercel Ecommerce template and want to use it with custom icons.
I have installed @svgr/webpack
and configured next.config.mjs:
export default {
images: {
formats: ['image/avif', 'image/webp'],
remotePatterns: [
{
protocol: 'https',
hostname: 'cdn.shopify.com',
pathname: '/s/files/**'
}
]
},
webpack(config) {
config.module.rules.push({
test: /.svg$/,
oneOf: [
{
resourceQuery: /react/, // ?react query => @svgr/webpack
use: ['@svgr/webpack']
},
{
type: 'asset/resource' // Default asset voor andere SVG's
}
]
});
return config;
}
};
In app/assets/icons/briefcase.svg I will save multiple svg files. Then I made a reusible component:
import React from 'react';
// import BriefcaseIcon from 'assets/icons/briefcase.svg';
import BriefcaseIcon from '@/icons/briefcase.svg';
const icons = {
briefcase: BriefcaseIcon
};
const Icon = ({ name, size = 24, color = 'currentColor', ...props }) => {
console.log('NAAM: ', name);
const SvgIcon = icons[name];
if (!SvgIcon) {
console.warn(`Icon '${name}' bestaat niet.`);
return null;
}
return <SvgIcon width={size} height={size} fill={color} {...props} />;
};
export default Icon;
Now when I try to use the component, I get the following error message:
React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.
If I console.log the icon, I get this object:
{
"src": "/_next/static/media/briefcase.59a4a40f.svg",
"width": 24,
"height": 24,
"blurDataURL": null,
"blurWidth": 0,
"blurHeight": 0
}
Any idea what might be wrong? Seems that the svg loader is not working properly.
2
Answers
There is a pattern I usually use in every project to add and utilize SVG icons:
Icons.tsx :
and u can import and use it like this:
Create react component for the svg import. i.e. for github:
then, use this component else where like so: