Desired usage
import MySVG from "./mySVG.svg?svgr"; // SVGR loader
<MySVG />
import Image from "next/image";
import mySVG from "./mySVG.svg"; // Default NextJS loader
<Image src={mySVG} alt="" /> // (width and height will be applied automatically)
Required next.config.js
webpack(config, { dev: isDev, isServer }) {
config.module.rules.push({
test: /\.svg$/i,
issuer: /\.[jt]sx?$/,
resourceQuery: /svgr/, // only use svgr to load svg if path ends with *.svg?svgr
use: ["@svgr/webpack"],
});
// Re-add default nextjs loader for svg
config.module.rules.push({
test: /\.svg$/i,
loader: "next-image-loader",
issuer: { not: /\.(css|scss|sass)$/ },
dependency: { not: ["url"] },
resourceQuery: { not: [/svgr/] }, // Ignore this rule if the path ends with *.svg?svgr
options: { isServer, isDev, basePath: "", assetPrefix: "" },
});
}
Required typescript declaration (if using ts)
declare module "*.svg?svgr";
How I figured it out
- Read these docs: https://react-svgr.com/docs/webpack/
- Used this snippet to get the default rule applying to svgs
webpack(config) {
const defaultSvgLoader = config.module.rules.find(
(rule) => typeof rule?.test?.test === "function" && rule.test.test(".svg")
);
console.log(defaultSvgLoader);
}
- Added
resourceQuery: { not: [/svgr/] }
into the logged output object so that *.svg?svgr
paths will be ignored