Markdown Math Rendering#
Waline renders mathematical formulas server-side using markdown-it with one of two pluggable backends: MathJax (default) or KaTeX. Math is processed during comment ingestion — not in the browser — so the rendered HTML is stored and served directly to clients.
Entry Point#
The core logic lives in packages/server/src/service/markdown/index.js. The exported getMarkdownParser(markdown) function accepts the server's markdown config object and returns a function (content) => sanitizedHtml. The parser is instantiated once at module load in comment.js, not per-request.
Backend Selection#
The tex config key (sourced from MARKDOWN_TEX) controls which engine is loaded :
MARKDOWN_TEX value | Engine | Output format |
|---|---|---|
mathjax (default) | @mdit/plugin-mathjax/sync via createMathjaxInstance | SVG |
katex | @mdit/plugin-katex | MathML |
false | Disabled | — |
KaTeX and MathJax options can be further tuned via MARKDOWN_KATEX and MARKDOWN_MATHJAX (both default to {}) .
The full markdown environment variable reference is in docs/src/en/reference/server/env.md and at waline.js.org/en/reference/server/env.html.
Dependencies#
Current pinned versions in packages/server/package.json:
@mdit/plugin-katex→0.25.2@mdit/plugin-mathjax→0.26.2@mathjax/src→^4.1.2and@mathjax/mathjax-tex-font→^4.1.2(replacedmathjax-full)
The MARKDOWN_TEX default is 'mathjax' . In config.js, the strings '0' and 'false' are coerced to boolean false.
ESM Migration (PR #3623)#
The @mdit/* plugin suite migrated to ESM-only in their v0.9.0 release . PR #3623 (merged 2026-05-29) absorbed this and performed a larger refactor:
- Replaced the local
./mathjax.jshelper with@mdit/plugin-mathjax/sync'screateMathjaxInstance+mathjaxPlugin. - Deleted
mathCommon.js,mathjax.js, andutils.jsfrompackages/server/src/service/markdown/. - Made
getMarkdownParseraccept amarkdownparameter so callers passthink.config('markdown')explicitly. - Replaced
mathjax-fullwith@mathjax/src+@mathjax/mathjax-tex-font.
Vercel Deployment: @waline/vercel ≥ 1.41.3#
The ESM migration introduced a breaking deployment change for Vercel users. Because @mdit/* plugins are ESM-only, Vercel's Node runtime requires the --experimental-require-module flag . Deployments on @waline/vercel ≥ 1.41.3 must update vercel.json to:
- Set
NODE_OPTIONS: "--experimental-require-module"in theenvblock. - Include MathJax font files in
includeFilesunder the build config :node_modules/@mathjax/mathjax-newcm-font/**/* node_modules/mhchemparser/**/* node_modules/ip2region/data/**
Skipping this update causes a server crash on startup. See issue #3706 for the complete vercel.json template.
Known Issues#
- MathJax + container syntax conflict (issue #3696): Mixing
$$…$$math blocks with unsupported:::infocontainer directives can trigger aCannot read properties of null (reading '4')500 error in@mdit/plugin-mathjax. Workaround: setMARKDOWN_TEX=katexorMARKDOWN_TEX=false. A proper fix is tracked in the open issue. - The MathJax
jsdomdependency is held onminorupdates due to jsdom v20+ being ESM-only — upgrade requires the same CJS-require-ESM capability .