Mathjax
Share
Flag
Related
How to render math in Vue or Nuxt?
There are several ways to write and render beautiful math on web. However, some methods can't be directly applied to Vue.js/Nuxt.js. In this article, we will explain how to use katex and mathjax to render math in Vue.js/Nuxt.js.KatexTo automatically render all math in all the pages, you need to use CDN to load katex :<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/poem-studio-favicon-black.svg">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.css" integrity="sha384-wcIxkf4k558AjM3Yz3BBFQUbk/zgIYC2R0QpeeYb+TwlBVMrlgLqwRjRtGZiK7ww" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.js" integrity="sha384-hIoBPJpTUs74ddyc4bFZSM1TVlQDA60VBbJS0oA934VSz82sBx1X7kSx2ATBDIyd" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/contrib/auto-render.min.js" integrity="sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk" crossorigin="anonymous"
onload="renderMathInElement(document.body);"></script>
<title>Manitori</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>If you are using Nuxt.js, then you need to change your nuxt.config.ts ://nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
link: [
{rel:'stylesheet', href:"https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.css", integrity:"sha384-wcIxkf4k558AjM3Yz3BBFQUbk/zgIYC2R0QpeeYb+TwlBVMrlgLqwRjRtGZiK7ww", crossorigin:"anonymous"}
],
script: [
{
defer:true,
src:"https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.js",
integrity:"sha384-hIoBPJpTUs74ddyc4bFZSM1TVlQDA60VBbJS0oA934VSz82sBx1X7kSx2ATBDIyd",
crossorigin:"anonymous"
},
{
defer:true,
src:"https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/contrib/auto-render.min.js",
integrity:"sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk",
crossorigin:"anonymous",
onload:"renderMathInElement(document.body);"
},
]
}
}
})If you want to specify the options of the renderMathInElement function, you could call renderMathInElement in another <script> :<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/poem-studio-favicon-black.svg">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.css" integrity="sha384-wcIxkf4k558AjM3Yz3BBFQUbk/zgIYC2R0QpeeYb+TwlBVMrlgLqwRjRtGZiK7ww" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.js" integrity="sha384-hIoBPJpTUs74ddyc4bFZSM1TVlQDA60VBbJS0oA934VSz82sBx1X7kSx2ATBDIyd" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/contrib/auto-render.min.js" integrity="sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk" crossorigin="anonymous"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
renderMathInElement(document.body, {
// customised options
// • auto-render specific keys, e.g.:
delimiters: [
{left: '$$', right: '$$', display: true},
{left: '$', right: '$', display: false},
{left: '\\(', right: '\\)', display: false},
{left: '\\[', right: '\\]', display: true}
],
// • rendering keys, e.g.:
throwOnError : false
});
});
</script>
<title>Manitori</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>Note that you'd better change document.body to a specific area document.getElementById(Id), otherwise, it may cause some fatal error, see Vue - TypeError: Cannot read properties of null (reading 'insertBefore'). To render math in a specific area, you need to call renderMathInElement separately in each page. For example:<script lang="ts" setup>
onMounted(()=>{
nextTick(()=>{
var node = document.getElementById(Id)
document.addEventListener("DOMContentLoaded", function() {
renderMathInElement(node, {
// customised options
// • auto-render specific keys, e.g.:
delimiters: [
{left: '$$', right: '$$', display: true},
{left: '$', right: '$', display: false},
{left: '\\(', right: '\\)', display: false},
{left: '\\[', right: '\\]', display: true}
],
// • rendering keys, e.g.:
throwOnError : false
});
});
})
})
</script>In Vue.js, you may need to asynchronously render math, so you can follow this example:<script lang="ts" setup>
var node = document.getElementById(Id)
Promise.resolve()
.then(()=>{
nextTick(()=>{
document.addEventListener("DOMContentLoaded", function() {
renderMathInElement(node, {
// customised options
// • auto-render specific keys, e.g.:
delimiters: [
{left: '$$', right: '$$', display: true},
{left: '$', right: '$', display: false},
{left: '\\(', right: '\\)', display: false},
{left: '\\[', right: '\\]', display: true}
],
// • rendering keys, e.g.:
throwOnError : false
});
});
})
})
</script>MathjaxIt is easy to automatically render all math using mathjax. Like katex, you'd better use CDN to load mathjax :<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/poem-studio-favicon-black.svg">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@4.0.0-beta.6/tex-chtml.js">
</script>
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
}
};
</script>
<title>Manitori</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>If you are using Nuxt.js, then change your nuxt.config.ts like this://nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
script: [
{
type: "text/javascript",
id: "MathJax-script",
async: true,
src: "https://cdn.jsdelivr.net/npm/mathjax@4.0.0-beta.6/tex-chtml.js",
},
{
innerHTML:
"MathJax = {tex: {inlineMath: [['$', '$'],['$$', '$$']]}};",
},
]
})However, in Vue.js you also need to asynchronously render math using mathjax, otherwise, The rendered math formula will revert back to original text. You can call MathJax.typesetPromise() to achieve this. For example:<script lang="ts" setup>
Promise.resolve()
.then(()=>{
nextTick(() => {
MathJax.typesetPromise();
});
})
</script>Or you could use setTimeout instead of nextTick:setTimeout(() => {
MathJax.typesetPromise();
}, 3000);Following our methods, you can easily integrate Vue.js/Nuxt.js with katex and mathjax😄!
2024-06-06 16:13:27