Display math formulas without any CSS or JS

MathML lets you insert math formulas with just HTML.

Since the release of Chrome 109 in January 2023, all web browsers displaying math formulas like below without any CSS or JavaScript.

f(w)=w0wf(w)=w 0w

This is done by writing MathML formulas. Similar to writing SVG images, MathML is an XML-based language that you can write inside of your HTML files. Browsers already know how to render this language, so you don’t need to do anything else except insert it into HTML.

<!--Markup for the above formula-->
<math>
<mrow>
<mi>f</mi>
<mo stretchy="false">(</mo>
<mi>w</mi>
<mo stretchy="false">)</mo>
<mo>=</mo>
<mi>w</mi>
<mn>0</mn>
<mi>w</mi>
</mrow>
</math>

LaTeX

Rather than learn how to write a new language, you can also use a processor to convert LaTeX inside of Markdown and MDX files automatically. By using the plugins remark-math and rehype-katex, you can write LaTeX formulas in any files that are processed with remark and rehype. This includes Astro, Next.js, and projects using MDX.

Then you can write LaTeX formulas like below.

$$f(w)=w 0w$$

The key is to configure the the KaTeX plugin properly. KaTeX can be used for rendering math formulas in browsers that don’t support MathML and for generating MathML directly. We only want to use it for generating MathML, so the library doesn’t need to be used client-side.

This is done by setting the output option to "mathml".

How to configure Astro

astro.config.mjs
import { defineConfig } from 'astro/config';
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
export default defineConfig({
markdown: {
remarkPlugins: [remarkMath],
rehypePlugins: [[rehypeKatex, { output: 'mathml' }]],
},
});

How to configure Next.js

next.config.mjs
import addMdx from '@next/mdx';
const nextConfig = {
pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'mdx'],
experimental: {
appDir: true,
},
};
addMdx(nextConfig, {
options: {
remarkPlugins: [remarkMath],
rehypePlugins: [[rehypeKatex, { output: 'mathml' }]],
},
});
export default nextConfig;

How to configure MDX

import { compile } from '@mdx-js/mdx';
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
await compile(file, {
remarkPlugins: [remarkMath],
rehypePlugins: [[rehypeKatex, { output: 'mathml' }]],
});