react-mathjax-component
v1.0.3
Published
React component to render math expressions with Mathjax through LiteDOM. Neither dangerouslySetInnerHTML nor real DOM insertion is necessary.
Downloads
41
Readme
React component for Mathjax
react-mathjax-component is a package to render math expressions as React element tree with Mathjax.
Basic usage is very simple. This renders $e = mc^2$. Visit the demo page to see how it works on your browser.
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.
Installation
npm install --save react-mathjax-component
This package assumes React v16 or later and uses Mathjax 3.2 or later.
Motivation
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.
Advanced usage
Customize Mathjax document object
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} />
);
Styling math expression element
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>
);
API
See the demo source for the working example.
import Mathjax from 'react-mathjax-component'
Signature:
function Mathjax(props: MathjaxProps): React.ReactElement
This returns SVG element tree rendered by Mathjax using the given properties.
import type { MathjaxProps } from 'react-mathjax-component'
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.
import type { Document } from 'react-mathjax-component'
Signature:
type Document = MathDocument<LiteElement, LiteText, LiteDocument>;
Type for document
property.
Bug report or feature request
Please create a new issue ticket.
License
This package is distributed under the MIT license.