Ignoring JSX Components in Vale for MDX-based Documentation
February 27, 2025
When using Vale to lint documentation written in MDX, a common challenge arises when the linter processes content inside custom JSX components, often leading to false positives.
Although Vale is markup-aware, its default settings may not correctly handle the syntax of embedded components. This post explores how to solve this issue by using BlockIgnores in your .vale.ini configuration to explicitly ignore specific JSX components during the linting process.
The Challenge with JSX in MDX
In an MDX-based documentation workflow, it is common to use JSX components to render dynamic or complex content, such as interactive terminals or styled alert boxes.
<Terminal
cmd={[
'# Install Tailwind CSS',
'$ npx expo add tailwindcss@3 postcss autoprefixer -- --dev',
'',
'# Create a Tailwind config file',
'$ npx tailwindcss init -p',
]}
/>
{/* or */}
<Alert type="warning">
The following feature is experimental.
</Alert>
Vale processes files in stages. It first identifies special syntax and then applies ignore patterns (BlockIgnores and TokenIgnores) before applying the configured style rules. The problem occurs when Vale's linter attempts to apply prose rules to the text content or props within these JSX components, as it may not recognize the component syntax as a block to be skipped.
Using BlockIgnores to Exclude Components
Vale's BlockIgnores configuration key allows you to define block-level patterns that should be completely skipped during linting. These patterns are defined using regular expressions in the .vale.ini file.
To ignore a self-closing <Terminal /> component, you can add the following rule:
# .vale.ini
# Ignore self-closing Terminal components
BlockIgnores = (?s)<Terminal.*?/>
The (?s) flag allows the . to match newline characters, ensuring the pattern works for multi-line component declarations. The .*? is a non-greedy match for any characters between the opening tag and the self-closing />.
This pattern can be extended to handle components that have children, such as the <Alert> component. Multiple patterns can be provided by separating them with a comma.
# .vale.ini
BlockIgnores = (?s)<Terminal.*?/>, (?s)<Alert>.*?</Alert>
Here, .*? matches the child text inside the opening and closing <Alert> tags, effectively ignoring the component and its content from linting.
After adding these configurations, it is important to test them to verify that Vale is correctly ignoring the intended blocks.
Conclusion
By leveraging Vale's BlockIgnores feature with custom regular expressions, you can create a robust documentation linting setup that gracefully handles JSX components within your MDX files. This ensures that your linter focuses only on the narrative content, avoiding false positives generated from component syntax.