解决 Next.js 中 “react/no-unescaped-entities” ESLint 错误的指南
引言
在 Next.js 中构建复杂界面时,经常会在 JSX 文本里包含特殊字符——例如引号(")、撇号(')以及尖括号(</>)。ESLint 规则 react/no-unescaped-entities 会禁止这些字符以“未转义”的形式出现在 JSX 中,否则可能导致解析或渲染异常。一旦触发,你会看到类似下面的错误:

./src/components/home/testimonials-section.tsx
74:17 Error: `"` can be escaped with `"`, `“`, `"`, `”`. react/no-unescaped-entities
74:53 Error: `"` can be escaped with `"`, `“`, `"`, `”`. react/no-unescaped-entities
info - Need to disable some ESLint rules? Learn more here: https://nextjs.org/docs/app/api-reference/config/eslint#disabling-rules
// Next.js 组件中的示例错误:
export default function Welcome() {
return <h1>Welcome to John's Blog</h1>;
// ^ 这里有未转义的撇号(apostrophe)
}
如果不处理,CI/CD 检查可能会失败,团队成员也会被相关的 Lint 警告干扰。本文将解释错误出现的原因,并给出多种可靠的修复方式。
根因解析
JSX 中的特殊字符规则
JSX 与 HTML 类似,但在文本解析上更严格。< 与 > 会被解析为元素分隔符,引号与撇号常用于界定属性值边界。如果在文本里直接使用这些未转义字符,可能会破坏抽象语法树(AST):
<p>Use <strong>bold</strong> for emphasis.</p>
// 这里的 "<strong>" 会被解析为嵌套元素,而不是字面文本。
Next.js 的默认 ESLint 配置
Next.js 内置了 ESLint 设置(@next/eslint-plugin-next),并扩展了 react 与 jsx-a11y 相关预设。默认情况下,React 预设包含:
"rules": {
"react/no-unescaped-entities": "error"
}
因此,只要 JSX 中出现未转义的实体,在开发或构建阶段都会报错。
为何富文本项目更易受影响
涉及多语言、Markdown 渲染或大量用户生成内容(UGC)的项目常常包含很多特殊字符,更容易触发未转义实体的告警,造成持续的 Lint 噪音,从而影响开发效率。
推荐方案:在 Next.js 中配置 ESLint
全局关闭该规则
若希望在整个项目范围内关闭 no-unescaped-entities,修改 .eslintrc.js:
module.exports = {
extends: ["next", "next/core-web-vitals"],
rules: {
"react/no-unescaped-entities": "off",
},
};
通过 next.config.js 调整构建期行为
如果你只想在构建阶段跳过 ESLint 校验,可修改 next.config.js:
module.exports = {
eslint: {
ignoreDuringBuilds: true, // skips all lint checks in production builds
},
};
⚠️ 该设置会在构建时静默所有 ESLint 错误,请谨慎使用。
在特定文件或组件中禁用
若只想在某个文件或组件内临时禁用,可添加内联 ESLint 指令:
/* eslint-disable react/no-unescaped-entities */
export default function Caution() {
return <p>Warning: Don't click that button!</p>;
}
/* eslint-enable react/no-unescaped-entities */
TypeScript 项目的注意事项
如果你在 tsconfig.json 中配置了路径别名,并配合 ESLint overrides 使用,请确认引用的 ESLint 配置无误:
// .eslintrc.js
module.exports = {
parser: "@typescript-eslint/parser",
extends: [
"next",
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended",
],
rules: {
"react/no-unescaped-entities": "off",
},
};
替代方案:使用 HTML 实体
如果你希望遵循该规则,同时又正确显示特殊字符,可以改用 HTML 实体。
常用 HTML 实体
| Character | Entity |
|---|---|
Apostrophe (') |
' or ' |
Double quote (") |
" |
Less-than (<) |
< |
Greater-than (>) |
> |
Ampersand (&) |
& |
在 JSX 中的正确用法
export default function Quote() {
return (
<p>
She said, "Next.js is awesome!" & I couldn't agree more.
</p>
);
}
适用场景
- 静态文案:页头、页脚或营销页中的硬编码文本。
- 本地化文件:在 JSON/YAML 中保存实体,便于跨语言传递。
- 对 SEO 关键的内容:确保源码中始终对特殊符号进行编码。
其他实用做法
使用花括号的 JavaScript 表达式
将文本包裹在花括号内,作为字符串字面量传入,避免 JSX 解析歧义:
export default function Ellipsis() {
return <p>{'Wait for it...'}</p>;
}
用单引号包裹含双引号的字符串(或反之)
如果字符串内部含有双引号,可用单引号包裹(或反过来):
// 避免字符串内未转义的双引号
<p title='She said "Hello" to me'>Greeting</p>
利用 React Fragment
当一段内容包含较复杂的标签与文本时,可用 Fragment 将文本与标签隔离:
export default function Mixed() {
return (
<>
<p>Use <strong>React</strong> & Next.js together!</p>
<p>{'Enjoy your coding journey.'}</p>
</>
);
}
总结与参考
| 方案 | 优点 | 缺点 |
|---|---|---|
| 全局关闭 ESLint 规则 | 见效快、无 Lint 噪音 | 可能掩盖真实的未转义问题 |
| 使用 HTML 实体 | 符合规范、明确编码 | 冗长、可读性下降 |
| 内联禁用 ESLint 注释 | 颗粒度细、可定点控制 | 指令分散在代码中,重复度高 |
| 使用花括号/替换引号的写法 | 不关闭 Lint 也能灵活处理 | 与惯用 JSX 写法略有差异 |
