#@svgr/webpack and url

1 messages · Page 1 of 1 (latest)

distant cove
#

With the @svgr/webpack is it possible to have both the react component and alternatively the url loader or default loader for nextjs and svg's?

weary pivotBOT
#

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.

distant cove
#

<@&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?

weary pivotBOT
#

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:

  1. Using query parameters to differentiate between component imports and URL imports
  2. Using different file extensions (like .svgr for components and .svg for 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.

distant cove
#

@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"?

weary pivotBOT
#

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:

  1. Resource query support is limited: According to issue #69502, Turbopack doesn't properly pass the resourceQuery from imports to loaders. This means that queries like ?react or ?url might not work as expected with SVG imports Github Issue #69502.

  2. 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.

  3. 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.

Note that these issues are being worked on, so future versions of Next.js with Turbopack may improve resource query support.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: