You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中使用SVG作为组件出现类型无效报错的解决方法

如何修复Next.js中SVG作为组件使用时的"type is invalid"错误?

报错信息

使用HomeIcon SVG图标组件时触发如下错误:

[ Server ] React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.

已执行的操作

  1. 配置next.config.mjs:
import createNextIntlPlugin from "next-intl/plugin";
const withNextIntl = createNextIntlPlugin();

/** @type {import('next').NextConfig} */
const nextConfig = {
   webpack: (config) => {
  // SVG
  // 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: [
        {
          loader: "@svgr/webpack",
          options: {
            typescript: true,
            ext: "tsx",
          },
        },
      ],
    }
  );

  // Modify the file loader rule to ignore *.svg, since we have it handled now.
  fileLoaderRule.exclude = /\.svg$/i;

  return config;
   },
};
export default withNextIntl(nextConfig);
  1. 在根目录创建svg.d.ts类型定义文件:
declare module "*.svg" {
  import React from "react";
  const SVG: React.VFC<React.SVGProps<SVGSVGElement>>;
  export default SVG;
}
  1. 在tsconfig.json中添加该类型文件:
"include": [
  "svg.d.ts",
  "next-env.d.ts",
  "**/*.ts",
  "**/*.tsx",
  ".next/types/**/*.ts",
  "next.config.mjs"
],
  1. 在Layout组件中使用SVG组件:
import Navbar from "@/components/Navbar";
import { FC, ReactNode, SVGProps } from "react";
import HomeIcon from "@/assets/home.svg";
import Image from "next/image";

interface layoutProps {
children: ReactNode;
locale: string;
}

const Layout: FC<layoutProps> = ({ children, locale }) => {
   return (
     <div>
       <Navbar locale={locale} />
       {children}

    <div className="px-7 bg-white shadow-lg rounded-2xl fixed bottom-0 right-0 left-0 border border-green-600">
      <div className="flex">
        <div className="flex-1 group">
          <a
            href="#"
            className="flex items-end justify-center text-center mx-auto px-4 pt-2 w-full text-gray-400 group-hover:text-green-800"
          >
            <span className="block px-1 pt-1 pb-1">
              <HomeIcon className="w-6 h-6" />
              <span className="block text-xs pb-2">Home</span>
              <span className="block w-5 mx-auto h-1 group-hover:bg-green-800 rounded-full"></span>
            </span>
          </a>
        </div>
    </div>
  </div>
);
};

export default Layout;

修复方案

1. 重构webpack SVG处理规则

原配置修改默认fileLoaderRule的方式易引发规则冲突,建议直接移除默认SVG规则后重新定义:

import createNextIntlPlugin from "next-intl/plugin";
const withNextIntl = createNextIntlPlugin();

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (config) => {
    // 移除默认的SVG处理规则
    config.module.rules = config.module.rules.filter(
      (rule) => !rule.test?.test?.(".svg")
    );

    // 添加SVGR规则:将不带?url后缀的SVG转为React组件
    config.module.rules.push(
      {
        test: /\.svg$/i,
        issuer: /\.[jt]sx?$/,
        resourceQuery: { not: /url/ },
        use: [
          {
            loader: "@svgr/webpack",
            options: {
              typescript: true,
              ext: "tsx",
            },
          },
        ],
      },
      // 保留资源加载规则:用于带?url后缀的SVG(作为静态资源导入)
      {
        test: /\.svg$/i,
        resourceQuery: /url/,
        type: "asset/resource",
      }
    );

    return config;
  },
};

export default withNextIntl(nextConfig);

2. 验证类型定义有效性

确认svg.d.ts无语法错误,且tsconfig.json的include数组已正确包含该文件。若类型定义不生效,可尝试将文件移至src目录(若项目使用src结构),或在tsconfig中明确指定文件路径。

3. 清理缓存并重启服务

执行以下命令清除Next.js缓存与依赖缓存:

rm -rf .next node_modules
npm install
npm run dev

4. 检查SVG文件与导入路径

确保@/assets/home.svg文件存在,同时验证tsconfig.json中路径别名@的配置正确:

"paths": {
  "@/*": ["./*"]
}

内容的提问来源于stack exchange,提问作者Mohammadreza Ataei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 11:35:14