If you are building a STEM web application, there is a certainty that you will need to render formulae, chemical reactions and equations. STEM audiences are used to writing these in LaTeX format. In this post, we will create a React component that can render these LaTeX equations with the help of the KaTeX library.
Latex equation to render
We will look at quadratic formula text for this blog post. If the text is
Given a general quadratic equation of the form
$$ax^{2} + bx + c = 0$$
with $x$ representing an unknown, with $a$, $b$ and $c$ representing constants, and with $a \ne 0$, the quadratic formula is:
$$x = \frac{-b \pm \sqrt{b^{2} - 4ac}}{2a}$$
The above block of text should be rendered as
❗️Spoiler❗️
The code for this is available here: https://github.com/kirankulkarni/next-katex
Setup details
For this post, I have used.
- Next JS 14.0.4
- Using Javascript
- Using the App router
- Tailwind CSS 3.3.0
- Katex 0.16.9
Step 1: Install katex in your NextJS setup
npm i katex
Step 2: Build a KatexSpan component that can render the equations
Step 2.1: Understanding Katex Auto Render extension usage.
We will be using the Katex Auto Render extension. This automatically detects equations in the child nodes and converts them into equations. You can find a detailed explanation here.
The auto render provides the function renderMathInElement
that takes a DOM node reference and options. The function will recursively search for text nodes inside this element and render the math in them. refer to API for more info
Step 2.2: Create a KatexSpan component file
Ensure that it’s a client component by mentioning use client;
as the first line of the file.
Step 2.3: Importing renderMathInElement
function
The Katex library does pack the extension, and hence, we can import it as
import renderMathInElement from 'katex/dist/contrib/auto-render';
import 'katex/dist/katex.min.css';
The imported katex.min.css
controls the look & feel of the rendered equations.
Step 2.4: Create a Ref for the node that will contain the text with equations
The Katex API renderMathInElement
needs a reference to the DOM node. We can use React Refs to get the reference to the DOM node that will have the text with equations.
const katexTextRef = useRef();
Ensure that you have imported useRef from React.
Step 2.5: Add JSX for the KatexSpan element
Since we want to use this as a span element, we will keep it simple.
return (
<div ref={katexTextRef} {...delegated}>
{text}
</div>
);
Note that we have used the ref
property to ensure that React provides a reference to this DOM node for us to use.
Step 2.6 Leverage useEffect
hook to run the KaTeX Autorender renderMathInElement.
Now, that we have the reference, we can use useEffect
that runs the first time after the DOM has been constructed.
useEffect(() => {
if (katexTextRef.current) {
renderMathInElement(katexTextRef.current, {
delimiters: [
{ left: '$$', right: '$$', display: true },
{ left: '$', right: '$', display: false },
],
});
}
}, []);
Notice that we are checking if KatexTextRef
has been assigned before running the auto render
Wiring it all up
'use client';
import renderMathInElement from 'katex/dist/contrib/auto-render';
import 'katex/dist/katex.min.css';
import { useEffect, useRef } from 'react';
export default function KatexSpan({ text, ...delegated }) {
const katexTextRef = useRef();
useEffect(() => {
if (katexTextRef.current) {
renderMathInElement(katexTextRef.current, {
delimiters: [
{ left: '$$', right: '$$', display: true },
{ left: '$', right: '$', display: false },
],
});
}
}, [text]);
return (
<div ref={katexTextRef} {...delegated}>
{text}
</div>
);
}
Top comments (5)
Any way to handle html too..Like suppose I have html like
value : \frac{2}{3}
I want to render both html and katex...Like either dangerouslysetHtml or something else ?
Thank you @kirankulkarni, I was able to add Katex to the propositional logic quizzes at logicola.org/ because of you. Regards from Berlin!
Thank you.
I was struggling to implement latex with nextjs.
Finally, I found that I forgot to include 'use client'.
How can i do the same using typescipt
the process is same.
you just need to install Type Definition form npm website.