Rendering Pitfalls
Docusaurus renders markdown as MDX, which means the file is processed as a mix of markdown and JSX (React component syntax) before being rendered as HTML. This is stricter than standard markdown. The errors described on this page will either crash the page in dev mode, or - more critically - fail the CI/CD pipeline build, which rejects the commit and prevents the entire site from rendering until the error is fixed.
Always verify your changes in the dev preview container before committing. Dev mode is more lenient than the production build - if something looks wrong in dev mode, it will almost certainly fail the CI pipeline.
HTML Tags in Markdownβ
MDX parses HTML tags as JSX components. This means raw HTML in your markdown is legal - but only if it is valid JSX. Invalid or malformed HTML that would be silently ignored in a browser will cause a hard parse error in MDX.
Self-closing tagsβ
In HTML, <br> and <img> are void elements. In JSX they must be self-closed:
| Breaks MDX | Correct |
|---|---|
<br> | <br/> |
<img src="..."> | <img src="..."/> |
<hr> | <hr/> |
Unclosed tagsβ
Any opened HTML tag that is not closed will cause a parse error for the entire page:
<!-- This will crash the page -->
<div class="note">
Some content
<!-- This is fine -->
<div class="note">
Some content
</div>
HTML attributesβ
In JSX, attribute values must be quoted. Unquoted attribute values are invalid:
| Breaks MDX | Correct |
|---|---|
<img width=100/> | <img width="100"/> |
The safest approachβ
Avoid raw HTML entirely unless you specifically need it. Everything in a standard Crew Aid - callouts, tables, images, code blocks, headings - can be expressed in pure markdown syntax. Reserve HTML for edge cases where markdown falls short.
HTML comments <!-- --> are not valid MDX. They will cause a parse error. If you need to leave a note for authors, use a :::note callout or just write it in plain text and remove it before committing.
Bare Curly Braces { and }β
In MDX, { and } are JSX expression delimiters. A bare { in body text that is not part of a valid JSX expression will cause a parse error.
Common examples that break:
- Shell variable syntax:
${VARIABLE}in a prose sentence (not in a code block) - JSON examples written as inline text rather than in a code block
- Template strings with braces
Fix: Put anything with curly braces in a code block, or escape with a backslash:
<!-- This crashes -->
Set the value to ${MY_VAR} in the config.
<!-- This is fine -->
Set the value to `${MY_VAR}` in the config.
<!-- Or escape it -->
Set the value to \${MY\_VAR} in the config.
Bare < Charactersβ
A < followed by a letter is interpreted by MDX as the start of an HTML/JSX tag. Using it as a "less than" comparison in prose will cause a parse error if MDX can't match it to a closing tag.
Fix: Put comparisons in code blocks, or use the HTML entity <:
<!-- May crash -->
The value must be < 100.
<!-- Safe -->
The value must be `< 100`.
The value must be < 100.
Broken Internal Linksβ
Docusaurus validates every internal link ([text](./path)) at build time. A single broken link causes the entire site build to fail - all pages become unavailable until the broken link is fixed and the pipeline reruns.
Common causes:
| Cause | Example |
|---|---|
| File renamed or moved after link was written | ./old-page-name no longer exists |
| Wrong relative path | ../wrong-folder/page |
| Case mismatch | ./MyPage vs ./mypage (Linux CI is case-sensitive, Windows MIP is not) |
| Linked heading anchor doesn't match | Heading changed, anchor not updated |
| Linked asset doesn't exist |  |
The MIP runs Windows - file paths are case-insensitive on the MIP but case-sensitive on the Linux CI runner. A link that works in dev preview on the MIP may still fail the pipeline. Match the exact case of every filename and folder name in every link.
Verify before committing:
- Ensure the
crewaid-devservice is running (see Git Workflow) - Navigate to every page you edited
- Click every internal link and verify it loads
- Check the
crewaid-devservice logs - broken links print warnings even in dev mode
Special Characters in Table Cellsβ
The pipe character | is the table column delimiter in markdown. A bare | inside a table cell will break the table layout. Escape it with a backslash:
| Command | Effect |
|---|---|
| `net use \| findstr` | Broken - the pipe splits the cell |
| `net use \| findstr` | Correct - escaped pipe |
Similarly, avoid unescaped <, >, and { in table cells for the same JSX reasons described above.
VS Code Markdown Preview vs. Docusaurusβ
VS Code's built-in markdown preview does not render Docusaurus-specific syntax:
| Feature | VS Code Preview | Docusaurus |
|---|---|---|
:::tip callouts | Not rendered | Rendered correctly |
| Mermaid diagrams | Not rendered (without extension) | Rendered correctly |
#center image alignment | Ignored | Applied |
| MDX parse errors | Not flagged | Hard build failure |
| Broken internal links | Not checked | Hard build failure |
Always use the dev preview container to verify how your pages actually render. VS Code preview is only useful for quick sanity-checks of basic markdown structure.