Help needed! MDX, React, footnotes and Latex š¢
Footnotes in MDX React are... weird. Trying to use Latex in next-mdx-remote
can break the entire site.
This is a cry for help.
Background
I'm overhauling my blog in NextJs, and my expectation was that React and Markdown are both established enough technologies that they would kinda just work. Footnotes and latex aren't exactly edge cases either. Unfortunately, footnotes are failing entirely and latex won't work remote.
I created this repo/website as a testbed to try and fix these issues. Given that I haven't fully resolved them, it's now functioning as an illustration therein.
A more detailed journal of my struggles is on my blog
Stack, Code, Background
Github for this test website: github.com/HebeHH/reactmdxissues
Stack:
- Framework: NextJs and React
- Language: Typescript/Javascript
- Articles: Markdown/MDX
- Libraries:
next-mdx-remote
(remote),remark-math
andrehype-katex
(Latex)
Problems
Currently I am having issues with the following elements when doing MDX in React. I will update this with any new issues and answers:
- Footnotes
- Latex (when using remote)
Latex
Using Latex in markdown causes buildtime errors.
Background info:
- Latex is coded like
$$\frac{1}{e-x}$$
and should display like . - There's 3 ways to use MDX in NextJs: file-based routing, imports, and remote. My blog was trying to use remote with
next-mdx-remote
.
The problem: Using latex with remote routing doesn't work.
Latex with file-based or import routing is fine, as long remarkMath
and rehypeKatex
are installed as instructed. That's how I displayed the latex above, in this file-routed page.
However, even with those plugins installed, I get build errors with next-mdx-remote
:
ReferenceError: e is not defined
at \_createMdxContent (eval at compileMDX (file:///Users/hebe/Dropbox/Code/website/testing/node_modules/next-mdx-remote/dist/rsc.js:25:31), <anonymous>:21:53)
at MDXContent (eval at compileMDX (file:///Users/hebe/Dropbox/Code/website/testing/node_modules/next-mdx-remote/dist/rsc.js:25:31), <anonymous>:65:8)
at eh (/Users/hebe/Dropbox/Code/website/testing/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:134657)
....
ā Generating static pages (8/8)
Suspicions:
This is probably because next-mdx-remote
is doing some kind of parsing that's different from the native parsing.
Examples and try-it:
See this page for how Latex succeeds when it's served with normal file routing and the correct plugins. The code for this route is here on github; it's very straightforward.
Meanwhile the remote MDX page served here can only show a screenshot of the error message, otherwise I'd crash the app. To generate this yourself, clone the git repo and uncomment the environment = test
line in this page, then run bun run build
.
Footnotes
Footnotes in Markdown exhibit unexpected behavior, particularly when mixing single-string and longer-string footnotes.
Background info:
- Footnotes are typically coded like
[^1]
in the text, with a corresponding[^1]: Footnote content
at the bottom of the document. - The expected behavior is a clickable link at the reference point, leading to the footnote content at the bottom of the page.
The problem: Footnote behavior is inconsistent and often fails to work as expected.
-
Single-string footnotes:
- Create a
<sup>
footnote in the text - Generate a link, but to a page
domain/singleString
instead of the bottom of the current page. - No trace of the footnote text anywhere but the link; nothing at the bottom of the page
- Create a
-
Longer-string footnotes:
- Cause all subsequent footnotes to stop working entirely.
- Are treated as plain text, without creating any links or references.
Examples:
- Working single-string footnote: ^1
- Another working single-string: ^2
- Long-string footnote breaking subsequent ones: [^3]
- Failed single-string after a long one: [^4]
- Another failed long-string: [^5]
Suspicions:
The parser may not be extracting the post-[^]:
footnote reference correctly, causing a cascading failure in the footnote system.
Examples: The footnotes in this page should give a decent example.
You can also see this on this page for additional examples.
Compare this to the actual code in the Github.
[^3]: This is a longer test footnote that breaks subsequent footnotes [^4]: FailedSingleString [^5]: Another long footnote that doesn't work