react-mathjax-component is a package to render math expressions as React element tree with Mathjax.
Basic usage is very simple. This renders
import React from 'react';
import { createRoot } from 'react-dom/client';
import Mathjax from 'react-mathjax-component';
const root = document.getElementById('root');
createRoot(root).render(<Mathjax expr="e = mc^2"/>);
This package is built with the idea of converting Mathjax's LiteDOM into React element tree. It is
- Clean: No
dangerouslySetInnerHTML
. No hacky DOM manipulation. - Fast: React runtime can do differential update correctly. (Single math expression consists of bunch of SVG elements)
- Small: No complicated hack for DOM cache and no React context value. It's a single small functional component.
npm install --save react-mathjax-component
This package assumes React v16 or later and uses Mathjax 3.2 or later.
When you use Mathjax in React app, you would use dangerouslySetInnerHTML
. However it is not safe as you know.
And the React cannot do differential update for the inner HTML string.
Instead, you may use existing several React libraries for Mathjax. However all of them are relying on hacky real DOM manipulations.
In contrast, the idea of converting LiteDOM into React element tree does not need such hacks. And React runtime can do differential DOM update for the coverted React element tree. A simple math expression consists of bunch of SVG elements so this is important for performance.
LiteDOM is a small internal representation used by Mathjax to represent an SVG element tree. It was created to render math expressions on non-browser environment like Node.js. Mathjax converts LiteDOM tree into HTML string. This package converts it into React element tree instead.
By default, this package uses its own Mathjax document object. But you can use your own document object when
you want to customize some options (e.g. extra packages). It can be done through document
property.
import { mathjax } from 'mathjax-full/js/mathjax';
import { TeX } from 'mathjax-full/js/input/tex';
import { SVG } from 'mathjax-full/js/output/svg';
const yourDocument = mathjax.document('', {
InputJax: new TeX({ packages: ... }), // customize packages
OutputJax: new SVG({ fontCache: 'global' }), // customize cache strategy
});
const SomeComponent: React.FC<{expr: string}> = ({expr}) => (
<Mathjax expr={expr} document={yourDocument} />
);
React element tree returned from <Mathjax/>
component is a React fragment which contains a SVG
element tree. So you can style it as you like with its parent element.
const InlineMath: React.FC<{expr: string}> = ({expr}) => (
<span className="math-inline">
<Mathjax expr={expr} />
</span>
);
const RedMathBlock: React.FC<{expr: string}> = ({expr}) => (
<div className="math-block" style={{color: 'red'}}>
<Mathjax expr={expr} />
</div>
);
See the demo source for the working example.
Signature:
function Mathjax(props: MathjaxProps): React.ReactElement
This returns SVG element tree rendered by Mathjax using the given properties.
Signature:
interface MathjaxProps {
expr: string;
document?: Document;
}
expr
is the math expression to render.
document
is a Mathjax document object. Basically you don't need to set this property because this
package uses the default document object when it is not set.
Signature:
type Document = MathDocument<LiteElement, LiteText, LiteDocument>;
Type for document
property.
Please create a new issue ticket.
This package is distributed under the MIT license.