import { buildDynamicMDX } from 'nextra/remote'
import { Callout, RemoteContent as MathJaxExample, MathJax, MathJaxContext } from 'nextra/components'

# LaTeX

Nextra can use [KaTeX](https://katex.org) to pre-render LaTeX expressions directly in MDX or [MathJax](https://mathjax.org) to
dynamically render math in the browser.
To enable LaTeX support, you must enable the `latex` option in your `next.config.mjs` file:

```js filename="next.config.mjs" {4}
import nextra from 'nextra'

const withNextra = nextra({
  latex: true
})

export default withNextra()
```

A value of `true{:js}` will use KaTeX as the math renderer. To explicitly specify the renderer, you may instead provide an
object `{ renderer: 'katex' }{:js}` or `{ renderer: 'mathjax' }{:js}` 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:

~~~mdx
```math
\int x^2
```
~~~

## Example

For example, the following Markdown code:

~~~md filename="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:

<div className="mt-6 rounded-xl border border-gray-200 p-4 dark:border-gray-900">
  The **Pythagorean equation** is $a=\sqrt{b^2 + c^2}$ and the quadratic formula:

  ```math
  x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}
  ```
</div>

You can still use [Markdown and MDX syntax](../markdown) in the same line as your LaTeX expression.

<Callout>
  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\$.
</Callout>

## API

### KaTeX

`rehype-katex` is used to pre-render LaTeX expressions in your content. You can pass
supported [KaTeX options](https://katex.org/docs/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.

```js filename="next.config.mjs" {4-8}
const withNextra = nextra({
  latex: {
    renderer: 'katex',
    options: {
      macros: {
        '\\RR': '\\mathbb{R}'
      }
    }
  }
})
```

See [KaTeX’s documentation](https://katex.org/docs/supported) for a list of supported commands.

### MathJax

When MathJax is enabled (by setting `latex: { renderer: 'mathjax' }{:js}`) math is rendered on page load via
[`better-react-mathjax`](https://github.com/fast-reflexes/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]

[^1]: This can be changed by setting [`{ options: { src: ... } }{:js}`](https://github.com/fast-reflexes/better-react-mathjax#src-string--undefined) in the Nextra config.

MathJax rendering is enabled by setting `renderer: 'mathjax'{:js}` in your Nextra config.

```js filename="next.config.mjs" {3}
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](https://docs.mathjax.org/en/latest/options/index.html). However, note that you can only pass serializable
options to `better-react-mathjax` via the `options` key in your Nextra config.[^2]

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

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

```js filename="next.config.mjs" {4-12}
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](https://github.com/fast-reflexes/better-react-mathjax#src-string--undefined)
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).

```math
\int_2^3x^3\,\mathrm{d}x

```

<MathJaxExample components={{ MathJax, MathJaxContext }} />

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.


export async function getStaticProps() {
  const rawMdx = `~~~math
\\int_2^3x^3\\,\\mathrm{d}x
~~~
`
  const props = await buildDynamicMDX(
    rawMdx,
    {
      latex: {
        renderer: 'mathjax',
        options: {
          config: {
            tex: {
              macros: {
                RR: '\\mathbb{R}'
              }
            }
          }
        }
      },
    }
  )
  props.__nextra_dynamic_opts.title = 'LaTeX'
  return { props }
}
