Self-hosted MathJax
This directory contains a vendored copy of MathJax v4.1.2
(the tex-chtml configuration) plus the mathjax-newcm font it renders with. It is
served from our own origin and loaded by _includes/mathjax-custom.html on any page with
use_math: true in its front matter.
Why it’s vendored (not loaded from a CDN)
The site previously loaded MathJax from https://cdn.mathjax.org/.... That CDN was
retired in 2017 and now serves only a tiny JS shim that redirects to
cdnjs.cloudflare.com. The math therefore depended on two third-party domains
plus runtime script injection.
Some corporate networks (VPN / proxy / Zscaler-style TLS interception) block or
break those external requests, which made math fail to render — readers on those
machines saw raw $...$ LaTeX instead of equations.
Self-hosting removes every external domain from the math path. If a reader can load the blog, they can load the math engine, because it comes from the same origin.
v4 note: In MathJax v3 the font was bundled inside
tex-chtml.js. In v4 the font is a separate package (defaultmathjax-newcm) that the engine fetches at runtime — from a CDN unless told otherwise. So the font is vendored here too, and_includes/mathjax-custom.htmlsetsoutput.fontPathto this directory. Without that, self-hosting the engine alone would silently reintroduce the CDN dependency for fonts.
Why v4 (and displayOverflow: 'scale')
v4 added the output.displayOverflow option. We set it to 'scale', which shrinks any
display equation that is too wide for the 740px content column so it stays fully visible
and centered instead of overflowing into the sticky table of contents on the right. v3
had no built-in way to do this.
What’s included
To keep the footprint small (~3.7 MB instead of the full ~19 MB engine + ~50 MB font distribution), only the files actually loaded at runtime are vendored:
tex-chtml.js— the combined TeX-input + CommonHTML-output component ([mathjax]).input/tex/extensions/— TeX extensions autoloaded on demand (e.g.\color,\cancel,\require{...}).fonts/mathjax-newcm-font/— the CommonHTML newcm font: itschtml.jsentry pluschtml/woff2/(the WOFF2 files) andchtml/dynamic/(ranges loaded on demand, e.g. arrows, accents). Resolved viaoutput.fontPath→.../fonts/%%FONT%%-font.
The SVG output, MathML input bundles, the speech-rule engine (sre), the UI menu, and
the font’s svg/ + CommonJS/ESM (cjs/, mjs/) builds were intentionally excluded —
they are not used by this config.
How to update
To bump the version, re-vendor both the engine and the font (they share a version line):
# 1. Download and extract the engine and the newcm font npm tarballs
npm pack mathjax@<VERSION>
npm pack @mathjax/mathjax-newcm-font@<VERSION>
tar -xzf mathjax-<VERSION>.tgz # -> package/
tar -xzf mathjax-mathjax-newcm-font-<VERSION>.tgz -C font # -> font/package/
# 2. Replace the vendored engine paths (package/ is the tarball root in v4 — no es5/)
rm -rf assets/mathjax/tex-chtml.js assets/mathjax/input
cp package/tex-chtml.js assets/mathjax/
cp -R package/input/tex/extensions assets/mathjax/input/tex/extensions
# 3. Replace the vendored font (CHTML only)
rm -rf assets/mathjax/fonts/mathjax-newcm-font
mkdir -p assets/mathjax/fonts/mathjax-newcm-font/chtml
cp font/package/chtml.js assets/mathjax/fonts/mathjax-newcm-font/
cp -R font/package/chtml/woff2 assets/mathjax/fonts/mathjax-newcm-font/chtml/woff2
cp -R font/package/chtml/dynamic assets/mathjax/fonts/mathjax-newcm-font/chtml/dynamic
# 4. Rebuild and verify a math post renders (see below)
Verifying
bundle exec jekyll build
Then open any use_math: true post (e.g. /Reasoning-Models/) and confirm:
- equations render with the newcm font and the browser console shows no MathJax errors,
- the Network tab shows the font loading from this origin (
/assets/mathjax/fonts/...), not from acdn.jsdelivr.net/*.mathjax.orgURL, - a very wide display equation shrinks to fit the column instead of overflowing right.
