When webpage contents are reloaded dynamically, it is essential to re-render math with Mathjax. I’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.

   public function rendered()
    {
        $this->dispatch('mathjax-rerender');
    }

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 requestAnimationFrame() JavaScript function is used for seamless re-rendering.

<!-- MathJax Configuration BEFORE the script -->
<script>
    window.MathJax = {
      tex: {
        inlineMath: [
          ['$', '$'],
          ['\\(', '\\)']
        ],
        displayMath: [
          ['$$', '$$'],
          ['\\[', '\\]']
        ]
      },
      options: {
        enableMenu: false
      },
      startup: {
        ready: () => {
          // console.log('[MathJax] ready');
          MathJax.startup.defaultReady(); // continue MathJax startup
          
          // Initial render
          MathJax.typesetPromise()
            .then(() =>  console.log('[MathJax] initial render complete'))
            .catch(err => console.error('[MathJax] initial render error', err));
          
          // Function to render MathJax only in contest-problem-set component
          function renderMathJaxInProblemSet() {
            const containerElement = document.querySelector('.containers');

            if (problemSetElement) {
              // Clear existing MathJax first, then re-render
              MathJax.typesetClear([containerElement]);
              MathJax.typesetPromise([containerElement])
                .then(() => console.log('[MathJax] fast render completed'))
                .catch(err => console.error('[MathJax] render error', err));
            } else {
              MathJax.typesetClear();
              MathJax.typesetPromise()
                .then(() => console.log('[MathJax] full fast render completed'))
                .catch(err => console.error('[MathJax] full render error', err));
            }
          }
          
          // Listen for Livewire events to re-render MathJax
          Livewire.on('mathjax-rerender', () => {
            requestAnimationFrame(() => {
              renderMathJaxInProblemSet();
            });
          });
        }
      }      
    };
</script>

<!-- Load MathJax AFTER configuration -->
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>

JavaScript code above can be simplified as below needed.

<!-- MathJax Configuration BEFORE the script -->
<script>
    window.MathJax = {
      tex: {
        inlineMath: [
          ['$', '$'],
          ['\\(', '\\)']
        ],
        displayMath: [
          ['$$', '$$'],
          ['\\[', '\\]']
        ]
      },
      options: {
        enableMenu: false
      },
      startup: {
        ready: () => {
          MathJax.startup.defaultReady(); // continue MathJax startup
          
          // Initial render
          MathJax.typesetPromise();
          
          // Listen for Livewire events to re-render MathJax
          Livewire.on('mathjax-rerender', () => {
            requestAnimationFrame(() => {
              MathJax.typesetPromise();
            });
          });
        }
      }      
    };
</script>

<!-- Load MathJax AFTER configuration -->
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>