Table of Contents
How to render math in Astro - A detailed guide
Starting points#
is what we are going to use to render the math from the markdown documents. On a very high level it parses everything within $...$ or $$...$$ in your documents and applies css styles to it. The docs are pretty detailed although it can get somewhat vague at times; check them out here.
To wire this into Astro you need two plugins - remark-math (parses the $...$ and $$...$$ syntax into math nodes) and rehype-katex (turns those nodes into the actual HTML). Install both along with katex itself:
npm install remark-math rehype-katex katexNow, there are two ways to plug these into astro.config.mjs, depending on how much control you want over the markdown pipeline:
- If you are on the default markdown setup, you can just pass them as
markdown.remarkPluginsandmarkdown.rehypePlugins. - If you already have a custom
unified()processor (which is the case on this site, since Shiki config and other plugins live there too), plug them into that instead:
import { defineConfig } from "astro/config";import { unified } from "@astrojs/markdown-remark";import remarkMath from "remark-math";import rehypeKatex from "rehype-katex";
export default defineConfig({ markdown: { processor: unified({ remarkPlugins: [remarkMath], rehypePlugins: [rehypeKatex], }), },});Order matters here - remark-math runs on the markdown AST before it turns into HTML, rehype-katex runs after. Get this backwards and nothing renders, it just silently leaves your $...$ as plain text.
Customising #
does a somewhat poor job of explaining how to customise the styles in its own docs. It outlines here how the fonts can be customised, and you should - fonts differ considerably from the default, which is Computer Modern Roman.
Here is the procedure we actually use on this site:
- Motivation: We want to overwrite the default styles applies, as defined in
katex.min.css. - Self-host
katex.min.cssinstead of pulling it from a CDN - copy it fromnode_modules/katex/dist/katex.min.cssintopublic/styles/. Do the same for the font files innode_modules/katex/dist/fonts/if you plan to keep any of KaTeX’s own fonts. - Load another local stylesheet after
katex.min.css, which redefines only the classes you want to change.
<link rel="stylesheet" href="/styles/katex.min.css" /><link rel="stylesheet" href="/styles/katex-custom.css" />We take this one step further on this site and swap out ‘s own math fonts entirely for Computer Modern, so that math matches the rest of the body text. That means declaring @font-face rules for each font family and then remapping every class (.mathrm, .mathit, .mathbf, .mathcal, .mathfrak, and so on) to point at them:
@font-face { font-family: "ComputerModernRoman"; font-style: normal; font-weight: normal; src: url("/fonts/cm/cm-serif.ttf") format("truetype");}
.katex { font-family: "ComputerModernRoman";}.katex .mathrm { font-family: "ComputerModernRoman"; font-style: normal;}- Where does this local stylesheet go? Referring the Astro docs, local stylesheets live in
public/styles/. Same idea as how fonts live inpublic/fonts/. - Just open the actual
katex.min.cssfile to see the class names, then override whichever ones you care about. You can override colors, weights, whatever - not just fonts.
Extras#
If you want the exact fonts, download Computer Modern from here, self-host the .ttf files under public/fonts/, and wire them up in katex-custom.css as shown above. Two things worth remembering:
- Self-hosting means no CDN dependency and no request to a third party at page load - worth doing for a static site anyway.
- ’s own fonts still render fine if you skip this step - Computer Modern is a purely aesthetic choice to match a -like look.