-
-
Notifications
You must be signed in to change notification settings - Fork 425
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SVGR dynamic import with Webpack (& React Lazy?) #724
Comments
Same issue with me |
Hi, I am very surprised that it does not work. I think it is a webpack configuration issue more than a SVGR one. By looking at your example I have no idea why it does not work. Maybe someone else could guess. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
@jameswilson @julianklumpers |
How about for rollup, is there any way to load svg dynamically similar to webpack? |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
If anyone is finding this issue because they used the SVGR NextJS docs to setup webpack, removing the
FWIW I am using Next 13 with |
I'm facing a different problem, hopefully someone can help me. I have an UI library with an Icon component: import clsx from 'clsx';
import styles from './Icon.module.scss';
import { icons } from './icons';
import { Suspense, useMemo } from 'react';
export type IconName = keyof typeof icons;
export type IconProps = React.HTMLAttributes<HTMLDivElement> & {
icon: IconName;
disabled?: boolean;
};
export const Icon: React.FC<IconProps> = ({ icon, disabled = false, ...props }: IconProps) => {
const SvgIcon = useMemo(() => icons[icon], [icon]);
const classNames = clsx(styles.root, disabled ? styles.disabled : '', props.className);
if (!SvgIcon) return null;
return (
<div
{...props}
className={classNames}
>
<Suspense fallback={null}>
<SvgIcon style={{ width: '100%', height: '100%' }} />
</Suspense>
</div>
);
};
export default Icon; The content of my icons.ts looks like this import React from 'react';
const lazy = (componentImportFn: Function) =>
React.lazy(async () => {
let obj = await componentImportFn();
return typeof obj.default === 'function' ? obj : obj.default;
});
export const icons = {
Icon1: lazy(async () => import('./assets/ico-icon1.svg')),
Icon2: lazy(async () => import('./assets/ico-icon2.svg')),
Icon3: lazy(async () => import('./assets/ico-icon3.svg')),
Icon4: lazy(async () => import('./assets/ico-icon4.svg')),
} And my NextJs config looks like this as described here /** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
distDir: 'build-next-static',
swcMinify: true,
reactStrictMode: true,
webpack(config) {
// Grab the existing rule that handles SVG imports
const fileLoaderRule = config.module.rules.find((rule) => rule.test?.test?.('.svg'));
config.module.rules.push(
// Reapply the existing rule, but only for svg imports ending in ?url
{
...fileLoaderRule,
test: /\.svg$/i,
resourceQuery: /url/, // *.svg?url
},
// Convert all other *.svg imports to React components
{
test: /\.svg$/i,
// issuer: /\.[jt]sx?$/,
resourceQuery: { not: /url/ }, // exclude if *.svg?url
use: ['@svgr/webpack'],
}
);
// Modify the file loader rule to ignore *.svg, since we have it handled now.
fileLoaderRule.exclude = /\.svg$/i;
return config;
},
};
module.exports = nextConfig; And when calling the Icon button in a nextjs page e.g. import { Icon } from 'ui';
export default function Page() {
return (
<>
<Icon icon="Icon1" />
</>
);
} I'm getting the following error from nextjs Unhandled Runtime Error Can someone push me in a direction or better have a solution for me ? |
I have a similar problem, although with a slightly different error: So, usage looks something like this (we’re using const logos = {
brand1: lazy(() => import('path/to/brand1logo.svg')),
brand2: lazy(() => import('path/to/brand2logo.svg')),
};
const LogoComponent = ({ brand }) => {
const Logo = logos[brand];
return (
<Suspense fallback={null}>
<Logo />
</Suspense>
)
} …and what I’m getting in the console is the following:
It feels like we’re getting back something that isn’t a valid component, so React does not know what to do with it. In my head, I’d figure that |
Relevant addendum: We’re still on webpack In another greenfield project where we’re using Next, we’re able to do the above just fine (just using Next’s |
💬 Questions and Help
Thank you for this helpful project!
I'm trying to dynamically import SVGs based on a string filename, but I'm a little lost.
Is something like this possible using webpack
import
?When I run the webpack build, I get same error for every SVG in the folder.
webpack.config.js setup following docs:
I've tried adding
'file-loader',
to theuse
to no avail. Apologies if I'm off track in some obvious way, I'm fairly new to SVGR & React. I read somewhere that SVGR creates a mapping during build, so if there is a simpler way to just load the right SVG dynamically based on a string, an example would be great to have in docs. My apologies if this is documented already, I searched, scanned, and couldn't find anything relevant.The text was updated successfully, but these errors were encountered: