Guide to Resolving the "react/no-unescaped-entities" ESLint Error in Next.js
Introduction
Building rich user interfaces in Next.js often involves embedding text that contains special characters—such as quotes ("
), apostrophes ('
), and angle brackets (<
/>
). ESLint's react/no-unescaped-entities
rule prevents these characters from appearing unescaped in JSX, as they can lead to unexpected rendering or parsing issues. When triggered, you might see errors like:
./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
// Example error in a Next.js component:
export default function Welcome() {
return <h1>Welcome to John's Blog</h1>;
// ^ unescaped apostrophe here
}
Without addressing it, your CI/CD checks can fail, and collaborators may be confused by misleading lint warnings. This guide walks through why this error occurs and several robust fixes.
Understanding the Root Cause
JSX's Special Character Rules
JSX closely resembles HTML but is stricter with text parsing. Characters like <
and >
are parsed as element delimiters, while quotes and apostrophes denote attribute boundaries. Unescaped instances can break the AST:
<p>Use <strong>bold</strong> for emphasis.</p>
// The "<strong>" is interpreted as a nested element, not literal text.
Next.js's Default ESLint Configuration
Next.js ships with a built-in ESLint setup (@next/eslint-plugin-next
) that extends the react
and jsx-a11y
presets. By default, the React preset includes:
"rules": {
"react/no-unescaped-entities": "error"
}
As a result, any unescaped entity in your JSX triggers an error during development or build.
Why Rich-Text Projects Are More Affected
Projects with internationalization, markdown rendering, or heavy user-generated content tend to include many special characters. This increases the likelihood of unescaped entities and constant lint noise, slowing down development.
Recommended Solution: Configuring ESLint in Next.js
Disabling the Rule Globally
To suppress no-unescaped-entities
across your entire project, update your .eslintrc.js
:
module.exports = {
extends: ["next", "next/core-web-vitals"],
rules: {
"react/no-unescaped-entities": "off",
},
};
Adjusting ESLint via next.config.js
If you prefer to tweak ESLint only during builds, modify next.config.js
:
module.exports = {
eslint: {
ignoreDuringBuilds: true, // skips all lint checks in production builds
},
};
⚠️ This setting suppresses all ESLint errors on build, so use with caution.
Disabling on Specific Files or Components
To disable the rule in a single component or file, add an inline ESLint directive:
/* 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 */
Considerations for TypeScript Projects
If you use a tsconfig.json
path alias for lint overrides, ensure you reference the correct ESLint config:
// .eslintrc.js
module.exports = {
parser: "@typescript-eslint/parser",
extends: [
"next",
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended",
],
rules: {
"react/no-unescaped-entities": "off",
},
};
Alternative Solution: Using HTML Entities
When you prefer to honor the lint rule and still render special characters correctly, replace them with HTML entities.
Common HTML Entities
Character | Entity |
---|---|
Apostrophe (' ) |
' or ' |
Double quote (" ) |
" |
Less-than (< ) |
< |
Greater-than (> ) |
> |
Ampersand (& ) |
& |
Correct Usage in JSX
export default function Quote() {
return (
<p>
She said, "Next.js is awesome!" & I couldn't agree more.
</p>
);
}
When to Apply This Method
- Static copy: Hard-coded text in headers, footers, or marketing pages.
- Localization files: JSON or YAML where entities persist through translation.
- SEO-critical content: Ensures that the HTML source always encodes special symbols.
Other Practical Workarounds
JavaScript Expressions with Curly Braces
Wrap text in braces and use string literals to bypass JSX parsing:
export default function Ellipsis() {
return <p>{'Wait for it...'}</p>;
}
Single Quotes Instead of Double Quotes
If your string contains double quotes, wrap it in single quotes or vice versa:
// Avoids unescaped double quotes in a string
<p title='She said "Hello" to me'>Greeting</p>
Leveraging React Fragments
For complex blocks with mixed markup, fragments help isolate text from tags:
export default function Mixed() {
return (
<>
<p>Use <strong>React</strong> & Next.js together!</p>
<p>{'Enjoy your coding journey.'}</p>
</>
);
}
Summary & Reference Resources
Solution | Pros | Cons |
---|---|---|
Disable ESLint rule globally | Quick fix, zero lint noise | May hide genuine unescaped issues |
HTML Entities | Compliant, explicit encoding | Verbose, harder to read |
Inline ESLint disable comments | Granular control | Repetitive directives in code |
JS Expressions / Quotes swap | Flexible without disabling linting | Less idiomatic JSX |