Is it possible to import SVGs from a shared package in next 15?

In Next 14, I was able to import SVG files just fine as StaticImageData. After upgrading to Next 15, the only way I was able to get it to work was by adding this to my next config
// Grab the existing rule that handles SVG imports
const fileLoaderRule = config.module.rules.find((rule) => rule.test?.test?.('.svg'));

config.module.rules.push({
...fileLoaderRule,
test: /\.svg$/i
});

// Modify the file loader rule to ignore *.svg, since we have it handled now.
fileLoaderRule.exclude = /\.svg$/i;
// Grab the existing rule that handles SVG imports
const fileLoaderRule = config.module.rules.find((rule) => rule.test?.test?.('.svg'));

config.module.rules.push({
...fileLoaderRule,
test: /\.svg$/i
});

// Modify the file loader rule to ignore *.svg, since we have it handled now.
fileLoaderRule.exclude = /\.svg$/i;
This works fine, but in my PNPM monorepo I do some imports like this:
import EtsyIcon from '@something/shared-ui/src/assets/integration-icons/etsy-icon.svg';
import EtsyIcon from '@something/shared-ui/src/assets/integration-icons/etsy-icon.svg';
This no longer works and gives me this error:
Error: Image import "@something/shared-ui/src/assets/integration-icons/etsy-icon.svg" is not a valid image file. The image may be corrupted or an unsupported format.
Error: Image import "@something/shared-ui/src/assets/integration-icons/etsy-icon.svg" is not a valid image file. The image may be corrupted or an unsupported format.
How is this supposed to work? I saw a similar issue here but its slightly unrelated.
GitHub
@svgr/webpack Not working with svg's from shared package inside mon...
🐛 Bug Report Inside my monorepo I have a NextJS project and a shared 'icons' package which is just a folder full of svg files. Whenever I want to use @svgr/webpack with the below next.confi...
2 Replies
Jakov
Jakov2w ago
Try to tweak your next config Try this:
module.exports = {
webpack(config) {
const fileLoaderRule = config.module.rules.find((rule) => rule.test?.test?.('.svg'));

config.module.rules.push({
test: /\.svg$/i,
oneOf: [
{
issuer: { and: [/\.(js|ts|jsx|tsx|md|mdx)$/] },
resourceQuery: { not: [/url/] },
use: ['@svgr/webpack'],
},
{
type: 'asset',
resourceQuery: /url/,
},
{
use: [fileLoaderRule.loader, ...fileLoaderRule.options ? [{ options: fileLoaderRule.options }] : []].filter(Boolean),
exclude: [
/\.(js|ts|jsx|tsx|md|mdx)$/,
/node_modules\/(?!@something\/shared-ui)/,
]
},
],
});

fileLoaderRule.exclude = /@something\/shared-ui\/src/;

return config;
},
};
module.exports = {
webpack(config) {
const fileLoaderRule = config.module.rules.find((rule) => rule.test?.test?.('.svg'));

config.module.rules.push({
test: /\.svg$/i,
oneOf: [
{
issuer: { and: [/\.(js|ts|jsx|tsx|md|mdx)$/] },
resourceQuery: { not: [/url/] },
use: ['@svgr/webpack'],
},
{
type: 'asset',
resourceQuery: /url/,
},
{
use: [fileLoaderRule.loader, ...fileLoaderRule.options ? [{ options: fileLoaderRule.options }] : []].filter(Boolean),
exclude: [
/\.(js|ts|jsx|tsx|md|mdx)$/,
/node_modules\/(?!@something\/shared-ui)/,
]
},
],
});

fileLoaderRule.exclude = /@something\/shared-ui\/src/;

return config;
},
};
* We're using oneOf to apply different rules to SVG imports. * issuer: Checks where the SVG is being imported from. This lets us treat your monorepo source files differently. * resourceQuery: It checks if the svg import ends with ?url. * The first rule in oneOf uses @svgr/webpack for your monorepo's source files (during development). You'll need to install it: pnpm add @svgr/webpack -D * The second rule in oneOf handles svg imports, when svg files end with ?url. * The third handles all other cases, using Next.js image features. * fileLoaderRule.exclude: We exclude your monorepo's source directory from the original SVG rule, so Next.js's default handling doesn't interfere. If you're using TypeScript, add this to global.d.ts:
declare module '*.svg?url' {
const content: string;
export default content;
}

declare module '*.svg' {
import React = require('react');
export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
const src: string;
export default src;
}
declare module '*.svg?url' {
const content: string;
export default content;
}

declare module '*.svg' {
import React = require('react');
export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
const src: string;
export default src;
}
After making these changes delete your .next folder.
jakeleventhal
jakeleventhalOP7d ago
wish i had seen this sooner. funily enough ended up with basically the same solution

Did you find this page helpful?