Skip to content

fix(portal): catch unknown components and invalid MDX in content pages before readers see them - #444

Open
mehnoorsiddiqui wants to merge 1 commit into
devfrom
fix/portal-unknown-mdx-components
Open

mehnoorsiddiqui wants to merge 1 commit into
devfrom
fix/portal-unknown-mdx-components

Conversation

@mehnoorsiddiqui

Copy link
Copy Markdown
Contributor

Closes #442
Closes #443

The problem

Two kinds of mistake in an .mdx content page reached readers instead of the author:

What changes

The content check now refuses both. The CLI already parses every page the way the build does, so it now reports what it finds. portal generate and portal serve run this check at startup, and serve runs it again on every save in content/. On a refused save, the preview keeps the last version it accepted.

  • Unknown components: the check lists every tag that names a component which the page doesn't import or export, and which the portal doesn't register. Each one comes with a suggestion:
    • Typos: within two edits of a registered component, or one edit for names of three letters or fewer, so <Tip> is not taken for <Step>.
    • Components from Mintlify and Docusaurus, pointed to the portal's own:
      • Note, Tip, Info, Warning and the other admonitions → Callout
      • CardGroup → Cards
      • AccordionGroup → Accordions
      • CodeGroup → Tabs
      • TabItem → Tab
  • Invalid MDX: the check lists every broken page in one run, with paths relative to src. MDX's own wording is kept, without the parser's internals:
    ■  Pages in '…/src' are not valid MDX:
         • 'content/guides/components.mdx', line 138, column 12: Could not parse expression: Unexpected token
         • 'content/guides/other.mdx', line 7, column 1: Unexpected closing tag `</Tab>`, expected corresponding closing tag for `<Tabs>` on line 5
       MDX stops at the first mistake in a page, so a page can have more after the one shown.
    
    An unclosed tag is reported at the tag's own line. MDX only notices it at the end of the page and puts the tag's position in its message text, not in the error's location, so the CLI reads it from there.
  • Pages that still fail to render now fail the build. The static check can't see everything, for example a component inside a {…} expression. When a prerendered page holds React's marker for a part that threw on the server, the build now fails and quotes the error the server reported. That error used to fall outside the log lines the CLI shows.
  • The registered component list can't drift. mdx-components.test.ts reads portal-template/src/components/mdx.tsx and checks that it matches the CLI's list.

Not covered

  • Only the first mistake per page. MDX stops at the first mistake in a page, so a page with three unclosed <Cards> reports one of them, and the next appears once that one is fixed. The message says so. Listing every unclosed tag would need a tag-matching pass of our own, outside MDX, and could disagree with it.
  • serve doesn't start over broken content. It reports the problem and exits, as it already does for other content problems. Once it is running, a broken save is reported and the last good version stays in the preview.
  • The failed-render check reads React 19.2's markers. A unit test fails if react-dom leaves 19.2, so the markers get checked again on upgrade. The check watches the build's console.error for TanStack's render-error reports, because TanStack logs those errors nowhere else. It installs this only for vite build.

How it was tested

  • APIMATIC_E2E=1 npm test: 1967 passing, ESLint clean.
  • Two new end-to-end fixtures fail the build and show the page and the server's error in what the CLI prints:
    • failed-render: a component inside an expression.
    • failed-render-late: a component that suspends and then throws.
  • portal generate run by hand on a copy of the default fixture with broken pages. The output is shown above.
  • Every page in the existing fixtures still passes the new checks. The CLI parses with the same remark-mdx 3.1.1 and micromark extensions that @mdx-js/mdx 3.1.1 uses in the build, so both find the same syntax errors.

🤖 Generated with Claude Code

…s before readers see them

A page naming a component the portal does not provide, or a page that is not valid MDX,
is now refused by `portal generate` and `portal serve`, at startup and on save, with every
broken page listed by its line and column. A page that still fails to render while it is
prerendered fails the build, quoting the server's error.

Closes #442
Closes #443

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant