Nextra 3.0 is released. Read more

LaTeX

Nextra can use KaTeX to pre-render LaTeX expressions directly in MDX or MathJax to dynamically render math in the browser. To enable LaTeX support, you must enable the latex option in your next.config.mjs file:

next.config.mjs
import nextra from 'nextra'
 
const withNextra = nextra({
  latex: true
})
 
export default withNextra()

A value of true will use KaTeX as the math renderer. To explicitly specify the renderer, you may instead provide an object { renderer: 'katex' } or { renderer: 'mathjax' } as the value to latex: ....

When enabled, the required CSS and fonts will be automatically included in your site, and you can start writing math expressions by enclosing inline math in $...$ or display math in a math-labeled fenced code block:

```math
\int x^2
```

Example

For example, the following Markdown code:

page.md
The **Pythagorean equation** is $a=\sqrt{b^2 + c^2}$ and the quadratic formula:
 
```math
x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}
```

will be rendered as:

The Pythagorean equation is a=b2+c2a=\sqrt{b^2 + c^2} and the quadratic formula:

x=−b±b2−4ac2ax=\frac{-b\pm\sqrt{b^2-4ac}}{2a}

You can still use Markdown and MDX syntax in the same line as your LaTeX expression.

💡

If you want to display $ in your content instead of rendering it as an equation, you can escape it with a backslash (\). For example \$e = mc^2\$ will be rendered as $e = mc^2$.

API

KaTeX

rehype-katex is used to pre-render LaTeX expressions in your content. You can pass supported KaTeX options via the options key in your Nextra config. For example, to add a macro \RR that renders as \mathbb{R} you could use the following configuration.

next.config.mjs
const withNextra = nextra({
  latex: {
    renderer: 'katex',
    options: {
      macros: {
        '\\RR': '\\mathbb{R}'
      }
    }
  }
})

See KaTeX’s documentation for a list of supported commands.

MathJax

When MathJax is enabled (by setting latex: { renderer: 'mathjax' }) math is rendered on page load via better-react-mathjax instead of being pre-rendered. By default, MathJax is served via the MathJax CDN instead of the files being directly included in your site.1

MathJax rendering is enabled by setting renderer: 'mathjax' in your Nextra config.

next.config.mjs
const withNextra = nextra({
  latex: {
    renderer: 'mathjax'
  }
})

You can pass additional options to better-react-mathjax via the options key in your Nextra config. The config: ... option sets the MathJax configuration. However, note that you can only pass serializable options to better-react-mathjax via the options key in your Nextra config.2

For example, to configure MathJax to render \RR as \mathbb{R} you could use the following configuration.

next.config.mjs
const withNextra = nextra({
  latex: {
    renderer: 'mathjax',
    options: {
      config: {
        tex: {
          macros: {
            RR: '\\mathbb{R}'
          }
        }
      }
    }
  }
})

MathJax CDN

By default, MathJax is served via the MathJax CDN. To serve files from another location (including locally in your project), you must pass the src: ... option to the latex config. See the better-react-mathjax documentation for details about the src option. Additionally, you may need to copy the MathJax distribution into your /public folder for it to be served locally.

KaTeX vs. MathJax

With KaTeX, math is pre-rendered which means flicker-free and faster page loads. However, KaTeX does not support all of the features of MathJax, especially features related to accessibility.

The following two examples show the same formula rendered with KaTeX (first) and MathJax (second).

∫23x3 dx\int_2^3x^3\,\mathrm{d}x \[\int_2^3x^3\,\mathrm{d}x \]

Because of MathJax’s accessibility features, the second formula is tab-accessible and has a context menu that helps screen readers reprocess math for the visually impaired.

Footnotes

  1. This can be changed by setting { options: { src: ... } } in the Nextra config. ↩

  2. To pass non-serializable objects like Functions, you must use the <MathJaxContext config={...} /> component directly in your source. ↩