reactjs - How to import svg icons in Nextjs 15 - Stack Overflow
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',
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.
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.
Share Improve this question asked yesterday Reinier68Reinier68 3,2023 gold badges34 silver badges64 bronze badges2 Answers
Reset to default 2There is a pattern I usually use in every project to add and utilize SVG icons:
Icons.tsx :
export const Icons = {
Star: (props: React.SVGProps<SVGSVGElement>) => (
<svg
{...props}
fill="currentColor"
viewBox="4 4 48 48"
xmlns="http://www.w3.org/2000/svg"
>
<path d="m19.2 36.4-4.75-10.45L4 21.2l10.45-4.75L19.2 6l4.75 10.45L34.4 21.2l-10.45 4.75ZM36.4 42l-2.35-5.25-5.25-2.35 5.25-2.4 2.35-5.2 2.4 5.2 5.2 2.4-5.2 2.35Z" />
</svg>
),
};
and u can import and use it like this:
import { Icons } from "./Icons";
<Icons.Star className="size-5" />
and I use https://svg2jsx.com to convert the normal svg to jsx one.
Create react component for the svg import. i.e. for github:
import React from 'react';
interface Props {
width: number;
className?: string;
}
const GithubLogo = ({ width, className }: Props) => {
return (
<svg
xmlns='http://www.w3.org/2000/svg'
fill='currentColor'
width={width}
className={className}
viewBox='0 0 256 250'
>
<path
d='M128.001 0C57.317 0 0 57.307 0 128.001c0 56.554 36.676 104.535 87.535 121.46 6.397 1.185 8.746-2.777 8.746-6.158 0-3.052-.12-13.135-.174-23.83-35.61 7.742-43.124-15.103-43.124-15.103-5.823-14.795-14.213-18.73-14.213-18.73-11.613-7.944.876-7.78.876-7.78 12.853.902 19.621 13.19 19.621 13.19 11.417 19.568 29.945 13.911 37.249 10.64 1.149-8.272 4.466-13.92 8.127-17.116-28.431-3.236-58.318-14.212-58.318-63.258 0-13.975 5-25.394 13.188-34.358-1.329-3.224-5.71-16.242 1.24-33.874 0 0 10.749-3.44 35.21 13.121 10.21-2.836 21.16-4.258 32.038-4.307 10.878.049 21.837 1.47 32.066 4.307 24.431-16.56 35.165-13.12 35.165-13.12 6.967 17.63 2.584 30.65 1.255 33.873 8.207 8.964 13.173 20.383 13.173 34.358 0 49.163-29.944 59.988-58.447 63.157 4.591 3.972 8.682 11.762 8.682 23.704 0 17.126-.148 30.91-.148 35.126 0 3.407 2.304 7.398 8.792 6.14C219.37 232.5 256 184.537 256 128.002 256 57.307 198.691 0 128.001 0Zm-80.06 182.34c-.282.636-1.283.827-2.194.39-.929-.417-1.45-1.284-1.15-1.922.276-.655 1.279-.838 2.205-.399.93.418 1.46 1.293 1.139 1.931Zm6.296 5.618c-.61.566-1.804.303-2.614-.591-.837-.892-.994-2.086-.375-2.66.63-.566 1.787-.301 2.626.591.838.903 1 2.088.363 2.66Zm4.32 7.188c-.785.545-2.067.034-2.86-1.104-.784-1.138-.784-2.503.017-3.05.795-.547 2.058-.055 2.861 1.075.782 1.157.782 2.522-.019 3.08Zm7.304 8.325c-.701.774-2.196.566-3.29-.49-1.119-1.032-1.43-2.496-.726-3.27.71-.776 2.213-.558 3.315.49 1.11 1.03 1.45 2.505.701 3.27Zm9.442 2.81c-.31 1.003-1.75 1.459-3.199 1.033-1.448-.439-2.395-1.613-2.103-2.626.301-1.01 1.747-1.484 3.207-1.028 1.446.436 2.396 1.602 2.095 2.622Zm10.744 1.193c.036 1.055-1.193 1.93-2.715 1.95-1.53.034-2.769-.82-2.786-1.86 0-1.065 1.202-1.932 2.733-1.958 1.522-.03 2.768.818 2.768 1.868Zm10.555-.405c.182 1.03-.875 2.088-2.387 2.37-1.485.271-2.861-.365-3.05-1.386-.184-1.056.893-2.114 2.376-2.387 1.514-.263 2.868.356 3.061 1.403Z'
fill='currentColor'
/>
</svg>
);
};
export default GithubLogo;
then, use this component else where like so:
import GithubLogo from '@/components/assets/svg/social-media/github.logo';
const Page = () => {
return (
<Label className='flex flex-row items-center space-x-2'>
<GithubLogo size={24} />
<p>Github</p>
</Label>
)
}
- Windows 8—微软反击苹果的终极武器
- typescript - tag a href download filename nextjs - Stack Overflow
- excel - Sum with multiple criteria and first matches only (excluding duplicates) - Stack Overflow
- python - ConnectionError(err, request=request) requests.exceptions.ConnectionError: ('Connection aborted.', Remo
- swiftui - ShareLink with custom type produces error - Stack Overflow
- typescript - Command 'pod install' failed, Cause: binbash -c - Stack Overflow
- c - Interrupts on STM32F407G discovery Micro controller with HAL library to blink led - Stack Overflow
- vue.js - single pages doesn't work when i moved them to app component - Stack Overflow
- reactjs - Flatlist scrolling freeze - Stack Overflow
- javascript - Mapping through these JSON elements - Stack Overflow
- amazon web services - Problem with eventbridge when scheduling a rule - Stack Overflow
- reactjs - can not use an id that I saved in props as default value in react select - Stack Overflow
- python - Azure Cognitive Vector search query and index creation - Stack Overflow
- angular - How to resolve vitest errors; stylesheet imports and dynamically fetched modules - Stack Overflow
- node.js - How to extract frames in sequence as PNG images from ffmpeg stream? - Stack Overflow
- outlook - Unable to send email using Microsoft Graph API: Error 550 5.7.708 - Stack Overflow
- java - Is this a bug in the JVM, or in NASM? - Stack Overflow