How to use KaTex to render math formulas with Nextjs?
Tags: nextjs, react, mdx, math
Published: 2022-07-14 08:10:00

Here is an easy way to make it possible to implement math formulas inside MDX files within your Nextjs project. 

To do this we will use [KaTex](https://katex.org/) a math typesetting library and [contentlayer](https://www.contentlayer.dev/) to source the files.

As an example will render the formula for the Pythagorean theorem.

## Install packages
Assuming that you got Nextjs set up, we will need to install the following packages.

1. Install contentlayer

```
yarn add contentlayer next-contentlayer
```

2. Install `remark-math` and `rehype-katex` plugins.

```
yarn add remark-math rehype-katex
```

## Configure contentlayer
In `next.config.js` wrap configuration options with `withContentlayer`.
 
```js
import { withContentlayer } from 'next-contentlayer'
export default withContentlayer({})
```

In the root of the project create a file `contenlayer.config.js` and add the configuration below.

```js
import { defineDocumentType, makeSource } from 'contentlayer/source-files'
 
const Post = defineDocumentType(() => ({
  name: 'Post',
  filePathPattern: `**/*.mdx`,
  contentType: "mdx",
  fields: {
    title: { type: 'string', required: true },
  },
}))
 
export default makeSource({
  contentDirPath: 'posts',
  documentTypes: [Post]
})
```

In this file, we have defined document type `Post` with a title field that is a string. The `contentDirPath` tells contentlayer the location of our sourced MDX files.

## Add theorem as content

Create an MDX file `posts/home.mdx`.

```mdx
---
title: Pythagorean theorem
---

a^2 + b^2 = c^2

a = side of right triangle
b = side of right triangle
c = hypotenuse
```
 
## Render home page

In `/pages/index.js` add the code below.

```jsx
import { useMDXComponent } from 'next-contentlayer/hooks';
import { allPages } from 'contentlayer/generated';

export const getStaticProps = () => {
  const page = allPages.find((page) => page._raw.sourceFileName === "home.mdx")
  return { props: { page } }
}

export default function HomePage({ page }) {
  const MDXContent = useMDXComponent(page.body.code)

  return (
    <div>
      <h1>{page.title}</h1>
      <MDXContent />
    </div>
  )
}
```

## Render formula

We are almost there! If you boot up the app you will see that we are rendering `a^2 + b^2 = c^2`. Instead, you want to render the formula like this:

![Pythagorean theorem](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i93ihosoy4i3nda93j72.gif)
 
To make it work you, have add `remark-math` and `rehype-katex` to contentlayer configuration.

```jsx
import { makeSource } from 'contentlayer/source-files';
import remarkMath from "remark-math";
import rehypeKatex from "rehype-katex";

export default makeSource({
  // ...
  mdx: { 
    remarkPlugins: [remarkMath], 
    rehypePlugins: [rehypeKatex],
  },
})
```

The plugins will convert KaTex into HTML. To style the formula we need to load a CSS file.

```jsx
import Head from "next/head";

export default function HomePage({ page }) {
  return (
    <>
      <Head>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css" integrity="sha384-Xi8rHCmBmhbuyyhbI88391ZKP2dmfnOl4rT9ZfRI7mLTdk1wblIUnrIq35nqwEvC" crossOrigin="anonymous">
      </Head>
      ...
    </>
  )
}
```

And this is it, we just implemented KaTex in MDX.