#@svgr/webpack and url
1 messages · Page 1 of 1 (latest)
Hi @distant cove. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
Yes, it's possible to use both @svgr/webpack for React components and maintain URL loading functionality for SVGs in Next.js. There are a couple of approaches to achieve this:
Option 1: Using file extensions or query parameters
You can configure your Next.js project to use different loaders based on file extensions or query parameters:
// next.config.js
module.exports = {
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: { not: /\.(css|scss|sass)$/ },
resourceQuery: { not: /url/ }, // exclude if *.svg?url
loader: '@svgr/webpack',
options: {
dimensions: false,
titleProp: true,
},
}
);
// Modify the file loader rule to ignore *.svg, since we have it handled now.
fileLoaderRule.exclude = /\.svg$/i;
return config;
},
}
This configuration allows you to:
- Import SVGs as React components:
import Icon from './icon.svg' - Import SVGs as URLs:
import iconUrl from './icon.svg?url'
Option 2: Using different file extensions
Another approach is to rename SVG files you want to use as components with a different extension:
// next.config.js
module.exports = {
experimental: {
turbo: {
rules: {
'*.svgr': {
loaders: ['@svgr/webpack'],
as: '*.js',
},
},
},
},
webpack: (config) => {
config.module.rules.push({
test: /\.svgr$/,
use: '@svgr/webpack',
});
return config;
},
}
Then you can import them differently:
- For React components:
import IconComponent from '@root/public/icons/icon.svgr' - For URLs:
import iconUrl from '@root/public/icons/icon.svg'
Important considerations
When using SVGs in CSS files, be aware that there's a known issue with Turbopack where @svgr/webpack transforms all SVG imports to JS files, breaking those in CSS. This is documented in an open GitHub issue #71275.
For Next.js 15+ users, note that the Turbopack configuration should be placed under the experimental key:
const nextConfig = {
experimental: {
turbo: {
rules: {
"*.svg": {
loaders: ["@svgr/webpack"],
as: "*.js",
},
},
},
},
};
This is because there was a documentation inconsistency that was fixed in canary releases but not yet in stable documentation at the time of some reports Github Issue #71902.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@distant cove Kapa.ai is still learning and improving, please let me know how I did by reacting below.
<@&1089670008898080870> I'm using turbopack and i'm on the canary version.
Is it not possible to have a query, for example import ReactSVG from "./example.svg?react" or import SrcSVG from "./example.svg?url"
@weary pivot did you get my last question?
Let me check the knowledge base for you again. Give me one moment! :books:
Yes, I received your last question about using both @svgr/webpack for React components and URL loading functionality for SVGs in Next.js. I provided a detailed answer with two different approaches:
- Using query parameters to differentiate between component imports and URL imports
- Using different file extensions (like
.svgrfor components and.svgfor URLs)
I also mentioned some important considerations regarding Turbopack and CSS imports of SVGs, along with the proper configuration for Next.js 15+.
Is there something specific from my previous answer you'd like me to clarify or expand upon?
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@distant cove Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@weary pivot I'm using turbopack and i'm on the canary version, Is it not possible to have a query, for example import ReactSVG from "./example.svg?react" or import SrcSVG from "./example.svg?url"?
Let me check the knowledge base for you again. Give me one moment! :books:
Based on the knowledge sources, there are some limitations with resource queries in Turbopack that affect your use case.
When using Turbopack with Next.js canary versions, there are several issues with resource queries that have been reported:
-
Resource query support is limited: According to issue #69502, Turbopack doesn't properly pass the
resourceQueryfrom imports to loaders. This means that queries like?reactor?urlmight not work as expected with SVG imports Github Issue #69502. -
Aliased imports with resource queries: There's also an issue (#72561) where resource queries are ignored on aliased imports (using
@/path aliases) Github Issue #72561. -
Dynamic resource queries: Another issue (#71453) shows that dynamic resource queries (where the query value is determined at runtime) aren't properly passed in Webpack loaders with Turbopack enabled Github Issue #71453.
For SVG handling specifically, there's an open issue (#71275) about not being able to specify the issuer with @svgr/webpack loader in Turbopack, which causes invalid URL transformation in CSS Github Issue #71275.
As a workaround, one user suggested using different file extensions instead of query parameters:
experimental: {
turbo: {
rules: {
'*.svgr': {
loaders: ['@svgr/webpack'],
as: '*.js',
},
},
},
},
webpack: (config) => {
config.module.rules.push({
test: /\.svgr$/,
use: '@svgr/webpack',
});
return config;
}
Then you would import them like:
import IconComponent from '@root/public/icons/icon.svgr'; // For React components
import iconUrl from '@root/public/icons/icon.svg'; // For URLs
This approach avoids the resource query issues in Turbopack while still allowing you to use both React components and URL imports for SVGs.