MDX Sanitizer
Comprehensive MDX content sanitizer that prevents JSX parsing errors caused by angle brackets, generics, and other conflicting patterns.
The Problem
MDX 2.x treats unescaped < and { as JSX syntax. This causes build failures when content contains:
-
TypeScript generics: Promise<T> , Array<string> , Map<K, V>
-
Comparisons: <100ms , <= , >=
-
Arrows: --> , <-- , ->
-
Invalid tags: <link> in prose, <tag> placeholders
-
Empty brackets: <>
Solution Architecture
This skill implements a three-layer defense:
- Sync-Time Sanitization (Proactive)
Content is sanitized when syncing from .claude/skills/ to website/docs/ :
-
syncSkillDocs.ts
-
Main skill files
-
syncSkillSubpages.ts
-
Reference files
-
doc-generator.ts
-
Generated docs
- Pre-Commit Validation (Reactive)
The git pre-commit hook validates files before commit using validate-brackets.js .
- Build-Time Validation (Final Check)
npm run validate:all runs as part of prebuild to catch any issues.
Usage
Check for Issues (Dry Run)
cd website npm run sanitize:mdx
or with verbose output
npm run sanitize:mdx -- --verbose
Fix All Issues
cd website npm run sanitize:mdx -- --fix
or shorthand
npm run fix:mdx
Programmatic API
import { sanitizeForMdx, validateMdxSafety, isMdxSafe } from './lib/mdx-sanitizer';
// Sanitize content
const result = sanitizeForMdx(content, { useHtmlEntities: true });
if (result.modified) {
console.log(Fixed ${result.issues.length} issues);
fs.writeFileSync(path, result.content);
}
// Validate without modifying const issues = validateMdxSafety(content, 'path/to/file.md');
// Quick check if (!isMdxSafe(content)) { // Handle issues }
Escaping Strategies
The sanitizer uses HTML entities for maximum compatibility:
Pattern Original Escaped
Less-than <
<
Greater-than
>
Generics <T>
&lt;T&gt;
Comparison <=
&lt;=
Content inside code blocks (``` or ` ) is automatically protected and never escaped.
Files Modified
-
website/scripts/lib/mdx-sanitizer.ts
-
Core sanitizer module
-
website/scripts/sanitize-mdx.ts
-
CLI wrapper
-
website/scripts/syncSkillDocs.ts
-
Integration
-
website/scripts/syncSkillSubpages.ts
-
Integration
-
website/scripts/lib/doc-generator.ts
-
Integration
-
website/package.json
-
npm scripts
Patterns Detected
-
Less-than before digit: <100 , <0.5ms
-
Comparison operators: <= , >=
-
Empty brackets: <>
-
Arrows: <-- , -->
-
Generic types: Promise<T> , Array<string>
-
Space after less-than: < value
-
Invalid pseudo-tags: <link> , <tag> (not valid HTML)
Troubleshooting
Build Still Fails After Running Sanitizer
-
Clear Docusaurus cache: npm run clear
-
Re-run sanitizer: npm run sanitize:mdx -- --fix
-
Rebuild: npm run build
False Positives
If valid JSX components are being escaped:
-
Ensure they use PascalCase (e.g., <MyComponent> )
-
Check they're valid HTML5 elements
Manual Escaping
For edge cases, manually escape in source:
-
Use backticks for inline code:
&lt;T&gt; -
Use fenced code blocks for multi-line
-
Use HTML entities: < and >
Sources
-
MDX Troubleshooting
-
TypeDoc MDX Issues