{"id":877,"date":"2025-08-15T22:36:34","date_gmt":"2025-08-16T02:36:34","guid":{"rendered":"https:\/\/waterloobae.com\/?p=877"},"modified":"2025-08-20T13:25:53","modified_gmt":"2025-08-20T17:25:53","slug":"laravel-how-to-re-render-math-with-mathjax-on-livewire","status":"publish","type":"post","link":"https:\/\/waterloobae.com\/blog\/2025\/08\/15\/laravel-how-to-re-render-math-with-mathjax-on-livewire\/","title":{"rendered":"[Laravel] How to re-render math with MathJax on Livewire"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">When webpage contents are reloaded dynamically, it is essential to re-render math with Mathjax. I&#8217;ve been experimenting to find out the best hooks and events to re-render math seamlessly. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First, dispatch the event that will be used for re-render in the <code>rendered()<\/code> hook of Livewire Component Class as below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">   public function rendered()\n    {\n        $this->dispatch('mathjax-rerender');\n    }\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then, place the JavaScript below in the Blade template you need to re-render math. Please note that configuration commands are placed before MathJax script of CDN and <code>requestAnimationFrame()<\/code> JavaScript function is used for seamless re-rendering.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">&lt;!-- MathJax Configuration BEFORE the script -->\n&lt;script>\n    window.MathJax = {\n      tex: {\n        inlineMath: [\n          ['$', '$'],\n          ['\\\\(', '\\\\)']\n        ],\n        displayMath: [\n          ['$$', '$$'],\n          ['\\\\[', '\\\\]']\n        ]\n      },\n      options: {\n        enableMenu: false\n      },\n      startup: {\n        ready: () => {\n          \/\/ console.log('[MathJax] ready');\n          MathJax.startup.defaultReady(); \/\/ continue MathJax startup\n          \n          \/\/ Initial render\n          MathJax.typesetPromise()\n            .then(() =>  console.log('[MathJax] initial render complete'))\n            .catch(err => console.error('[MathJax] initial render error', err));\n          \n          \/\/ Function to render MathJax only in contest-problem-set component\n          function renderMathJaxInProblemSet() {\n            const containerElement = document.querySelector('.containers');\n\n            if (problemSetElement) {\n              \/\/ Clear existing MathJax first, then re-render\n              MathJax.typesetClear([containerElement]);\n              MathJax.typesetPromise([containerElement])\n                .then(() => console.log('[MathJax] fast render completed'))\n                .catch(err => console.error('[MathJax] render error', err));\n            } else {\n              MathJax.typesetClear();\n              MathJax.typesetPromise()\n                .then(() => console.log('[MathJax] full fast render completed'))\n                .catch(err => console.error('[MathJax] full render error', err));\n            }\n          }\n          \n          \/\/ Listen for Livewire events to re-render MathJax\n          Livewire.on('mathjax-rerender', () => {\n            requestAnimationFrame(() => {\n              renderMathJaxInProblemSet();\n            });\n          });\n        }\n      }      \n    };\n&lt;\/script>\n\n&lt;!-- Load MathJax AFTER configuration -->\n&lt;script id=\"MathJax-script\" async src=\"https:\/\/cdn.jsdelivr.net\/npm\/mathjax@3\/es5\/tex-mml-chtml.js\">&lt;\/script>\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">JavaScript code above can be simplified as below needed.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">&lt;!-- MathJax Configuration BEFORE the script -->\n&lt;script>\n    window.MathJax = {\n      tex: {\n        inlineMath: [\n          ['$', '$'],\n          ['\\\\(', '\\\\)']\n        ],\n        displayMath: [\n          ['$$', '$$'],\n          ['\\\\[', '\\\\]']\n        ]\n      },\n      options: {\n        enableMenu: false\n      },\n      startup: {\n        ready: () => {\n          MathJax.startup.defaultReady(); \/\/ continue MathJax startup\n          \n          \/\/ Initial render\n          MathJax.typesetPromise();\n          \n          \/\/ Listen for Livewire events to re-render MathJax\n          Livewire.on('mathjax-rerender', () => {\n            requestAnimationFrame(() => {\n              MathJax.typesetPromise();\n            });\n          });\n        }\n      }      \n    };\n&lt;\/script>\n\n&lt;!-- Load MathJax AFTER configuration -->\n&lt;script id=\"MathJax-script\" async src=\"https:\/\/cdn.jsdelivr.net\/npm\/mathjax@3\/es5\/tex-mml-chtml.js\">&lt;\/script><\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>When webpage contents are reloaded dynamically, it is essential to re-render math with Mathjax. I&#8217;ve been experimenting to find out the best hooks and events to re-render math seamlessly. First, dispatch the event that will be used for re-render in the rendered() hook of Livewire Component Class as below. Then, place the JavaScript below in [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,14,1],"tags":[],"class_list":["post-877","post","type-post","status-publish","format-standard","hentry","category-it-tips","category-laravel","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/waterloobae.com\/blog\/wp-json\/wp\/v2\/posts\/877","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/waterloobae.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/waterloobae.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/waterloobae.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/waterloobae.com\/blog\/wp-json\/wp\/v2\/comments?post=877"}],"version-history":[{"count":3,"href":"https:\/\/waterloobae.com\/blog\/wp-json\/wp\/v2\/posts\/877\/revisions"}],"predecessor-version":[{"id":899,"href":"https:\/\/waterloobae.com\/blog\/wp-json\/wp\/v2\/posts\/877\/revisions\/899"}],"wp:attachment":[{"href":"https:\/\/waterloobae.com\/blog\/wp-json\/wp\/v2\/media?parent=877"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/waterloobae.com\/blog\/wp-json\/wp\/v2\/categories?post=877"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/waterloobae.com\/blog\/wp-json\/wp\/v2\/tags?post=877"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}