Next.js Discord

Discord Forum

Importing SVG's as components - NextJS 15

Unanswered
Serengeti posted this in #help-forum
Open in Discord
SerengetiOP
So I'm used to doing this in v14 and prior. Add the @svgr/webpack loader, and just import icons as components and use however you want.

However I CANNOT get this to work in nextjs 15 and no-one seems to be having this issue.

Followed all the steps here: https://react-svgr.com/docs/next/

My import is like: import SpotifyIcon from '@/images/spotify.svg' (verified this exists)

This (attached image) is the error I get. Any help would be mega appreciated!

19 Replies

Can you try removing turbopack flag?
SerengetiOP
New error without turbopack
Are you passing the component as props? Maybe you can make a dictionary on the client component and pass just string "Spotify" and look for it inside the dictionary on the client component
SerengetiOP
No it's just being imported and used in the same component
SerengetiOP
I haven't added that, although now I've removed the turbopack flag I shouldn't need to right?
next.config.mjs

/** @type {import('next').NextConfig} */
const nextConfig = {
    reactStrictMode: true,
    images: {
        dangerouslyAllowSVG: true,
        remotePatterns: [
            {
                protocol: 'https',
                hostname: 'cdn.sanity.io',
            },
            {
                protocol: 'https',
                hostname: 'i.vimeocdn.com',
            },
        ],
    },
    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: fileLoaderRule.issuer,
                resourceQuery: {
                    not: [...fileLoaderRule.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
    },
}

export default nextConfig
import { PlatformLinkType } from '@/sanity/schemaTypes/objects/platformLink'

import AppleIcon from '@/images/apple-podcast.svg'
import LinkedinIcon from '@/images/linkedin.svg'
import SpotifyIcon from '@/images/spotify.svg'
import GenericIcon from '@/images/web.svg'
import YoutubeIcon from '@/images/youtube.svg'

type Props = {
    data: PlatformLinkType
    template?: string
}

const PlatformLink: React.FC<Props> = ({ data, template }) => {
    if (!data.platform) {
        return null
    }

    console.log(SpotifyIcon)

    return (
        <a href={data.url} target="_blank" className="group">
            <SpotifyIcon />

            <span className="text-red group-hover:underline">Link</span>
        </a>
    )
}

export default PlatformLink
At the moment I've got no logic involved at all, I've stripped it out until I can just get an SVG rendering correctly. This is exactly how I've had done it in v14
Try add that config to fix turbopack, if that doesn't work we keep debugging without turbopack
Did u rerun the server after removing turbopack?
SerengetiOP
Added the config option gives me the same error as before (WITHOUT TURBOPACK FLAG)

With the turbopack flag renabled, I still get the same error with this extra config option. So no joy there.
Yes I did a full rerun after each change (even though nextjs refreshes config changes) just to be safe
I have 2 ideas left
Trying to make PlatformLink client component
Or making PlatformLink a wrapper and the icon a children
SerengetiOP
client component no joy
SerengetiOP
Got it, thank you!
Do you know if you have to apply loader options in the turbopack config, or where the webpack config is actually defined?
Just trying to get viewBox retained now, so SVG's actually have a point
I don't know sorry