Search code examples
javascripthtmlmathjax

How do you insert MathJax (Latex) dynamically through JavaScript?


I have a LaTeX (which I am using MathJax to replicate) formula which works perfectly in HTML but when I try to inject it via .innerHTML this fails.

Under normal HTML I get this: enter image description here

But when I use this code in JS:

document.getElementById("si_suvat_equation").innerHTML = 
"<span>\begin{gather} s = ut + \frac{1}{2}  at^{2}\\ \notag end{gather}</span>";

Then I get this: enter image description here

So how do I get it so that my injected HTML looks like the original HTML? I am assuming JS is reading something as though it is code instead of just injecting it raw. But I am not sure how to change that so it is injecting the raw code only.


Solution

  • Some things to do:

    • In a JavaScript string literal, the backslash has a special meaning. There are several ways to get around this, but since in LaTeX syntax backslashes are very common, it is probably best to use String.raw so that backslashes are seen as literal backslashes.

    • You have a backslash missing before end{gather}

    • Mathematics needs to be surrounded with a delimiter, which by default is $$.

    • MathJax has a function typeset with which you can let the MathJax engine process the web page again to typeset newly added content. Please take note of the referenced documentation, as you may need to use typesetPromise instead.

    Here is a demo, where the static content is loaded correctly, and the div where the dynamic formula should appear is initialised with a button. When you click it, the dynamic code is executed and typeset is then called. As you can see this dynamic content is now also correctly typeset:

    document.querySelector("button").addEventListener("click", () => {
        document.getElementById("si_suvat_equation").innerHTML = 
    String.raw`<span>$$\begin{gather} s = ut + \frac{1}{2}  at^{2}\\ \notag \end{gather}$$</span>`;
        MathJax.typeset();
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.js"></script>
    
    <div>$$\begin{gather} s = ut + \frac{1}{2}  at^{2}\\ \notag \end{gather}$$ </div>
    
    <div id="si_suvat_equation"><button>Load</button></div>

    This snippet shows a message in the "console", which is related to the sandboxed environment of this Stack Snippet. It wouldn't be displayed in a more standard environment.