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

如何在NextJS 13中添加带可点击<a>标签的SVG组件?

解决Next.js中SVGR加载SVG内标签无法点击的问题

问题场景

在Next.js v13.4.2中使用SVGR v8.1.0加载SVG时,SVG内部的<a>标签无法触发点击跳转,相关代码如下:

SVG文件内容

<svg height='50'>
  <a href='#'><text x='0' y='20'>click in svg</text> </a>
</svg>

页面组件代码

import './globals.css'
import Vercel from '../public/vercel.svg'

export default function Home() {
  return (
    <main>
      <div>
        Hello World
        <Vercel />
      </div>
    </main>
  )
}

Next.js Webpack配置(next.config.js)

/** @type {import('next').NextConfig} */
const nextConfig = {
    webpack(config) {
        // 配置webpack通过SVGR处理SVG文件
        const fileLoaderRule = config.module.rules.find((rule) => rule.test?.test?.('.svg'));

        config.module.rules.push(
            // 针对带?url后缀的SVG使用原file-loader规则
            {
                ...fileLoaderRule,
                test: /\.svg$/i,
                resourceQuery: /url/,
            },
            // 其他SVG通过SVGR转换为React组件
            {
                test: /\.svg$/i,
                issuer: fileLoaderRule.issuer,
                resourceQuery: { not: [...fileLoaderRule.resourceQuery.not, /url/] },
                use: ['@svgr/webpack'],
            }
        );

        fileLoaderRule.exclude = /\.svg$/i;
        return config;
    },
}

module.exports = nextConfig

解决方案

1. 配置SVGR保留原生SVG元素

SVGR默认会将SVG中的<a>标签转换为React的<a>组件,可能导致跳转行为异常。修改Webpack规则,添加native: true选项强制保留原生SVG元素:

// 修改next.config.js中的SVGR规则部分
{
    test: /\.svg$/i,
    issuer: fileLoaderRule.issuer,
    resourceQuery: { not: [...fileLoaderRule.resourceQuery.not, /url/] },
    use: [
        {
            loader: '@svgr/webpack',
            options: {
                native: true, // 保留原生SVG标签,不转换为React组件
            },
        },
    ],
}

2. 手动处理SVG跳转逻辑

如果上述配置无效,可以采用以下两种方式:

  • 直接嵌入SVG代码:将SVG内容直接写入React组件,绕过SVGR转换:
export default function Home() {
  return (
    <main>
      <div>
        Hello World
        <svg height='50'>
          <a href='#'><text x='0' y='20'>click in svg</text></a>
        </svg>
      </div>
    </main>
  )
}
  • 添加点击事件模拟跳转:给导入的SVG组件绑定onClick事件,手动触发跳转:
import Vercel from '../public/vercel.svg'

export default function Home() {
  const handleSvgClick = () => {
    window.location.href = '#';
  };

  return (
    <main>
      <div>
        Hello World
        <Vercel onClick={handleSvgClick} style={{ cursor: 'pointer' }} />
      </div>
    </main>
  )
}

3. Next.js渲染纯HTML的方式

Next.js支持通过dangerouslySetInnerHTML渲染纯HTML内容,但该方式存在XSS风险,仅在必要时使用:

export default function Home() {
  const svgHtml = `
    <svg height='50'>
      <a href='#'><text x='0' y='20'>click in svg</text></a>
    </svg>
  `;

  return (
    <main>
      <div>
        Hello World
        <div dangerouslySetInnerHTML={{ __html: svgHtml }} />
      </div>
    </main>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 13:17:19