Skip to content

MathJax v4/v3 support: plugin emits v2 API config (MathJax.Hub.Config) regardless of loaded version #71

@cptkoolbeenz

Description

@cptkoolbeenz

Hi — thanks for maintaining this plugin. I'm reporting a latent bug that surfaces when the kblog_mathjax_custom_location override is used to load MathJax v3 or v4 from a CDN. I hit this while auditing a production WordPress site that's been on v4 for a while.

Summary

When kblog_mathjax_custom_location is set to a v3/v4 MathJax URL (e.g. https://cdnjs.cloudflare.com/ajax/libs/mathjax/4.0.0/tex-chtml.min.js), the plugin loads the v4 runtime successfully, but:

  1. class-mathjax-latex.php:223 unconditionally emits wp_add_inline_script('mathjax', 'MathJax.Hub.Config(' . wp_json_encode($mathjax_config) . ');') whenever the mathjax_config filter returns a non-empty array. MathJax.Hub does not exist in v3 or v4 — it was removed. The inline script throws TypeError: MathJax.Hub is undefined / ReferenceError: MathJax is not defined on every page load where the shortcode is present and a mathjax_config filter is registered.

  2. class-mathjax-latex.php::script_loader_tag() rewrites inline scripts on the mathjax handle from <script type='text/javascript'> to <script type='text/x-mathjax-config'>. That type is v2-specific — MathJax v3/v4 ignores it — so even the replacement wouldn't run.

  3. add_query_arg('config', $config, $mathjax_location) appends ?config=default to the script URL. v4 ignores this (its configuration model is window.MathJax = {...} set before the script loads), and for sites pointing at tex-chtml.min.js the query string is noise.

Visual rendering still works on v4-configured sites because v4's auto-typesetter runs independently of any Hub.Config() call — so the bug is often invisible to users but pollutes DevTools on every page load, and any customization registered via the mathjax_config filter is silently dropped on v4.

Reproduction

  1. Install this plugin on a site with MathJax enabled.
  2. In Settings → MathJax, set the custom location to https://cdnjs.cloudflare.com/ajax/libs/mathjax/4.0.0/tex-chtml.min.js (or any v3/v4 URL).
  3. Register a mathjax_config filter that returns any non-empty array, e.g.:
    add_filter('mathjax_config', fn() => ['TeX' => ['equationNumbers' => ['autoNumber' => 'AMS']]]);
  4. Visit any page containing the [mathjax] shortcode and open DevTools → Console.
  5. Observe: ReferenceError: MathJax is not defined at the emitted MathJax.Hub.Config({...}) inline script.

Suggested fix

Detect the loaded version from the script URL and branch config emission:

  • If URL matches a v3/v4 pattern (e.g. /mathjax/[34]\., or ends with tex-chtml, tex-mml-chtml, tex-svg, etc.):
    • Emit window.MathJax = {...} as an inline script with position 'before' (so it runs before the library loads and is picked up by v4's config reader).
    • Translate v2 config keys to v4 equivalents where possible (TeX.equationNumbers.autoNumber: 'AMS'tex.tags: 'ams', tex2jax.inlineMathtex.inlineMath, etc.).
    • Skip the script_loader_tag type rewrite for v3/v4.
    • Don't append ?config=default to the URL.
  • Otherwise, keep the existing v2 behavior (fully backward compatible).

A helper is_mathjax_v4($url) of ~5 lines handles the detection. The branching in add_script() and script_loader_tag() is maybe 20 lines total. The v2→v4 config key translation can start minimal (just tex.tags and tex.inlineMath / tex.displayMath) and expand over time — or just emit the raw dict under a tex key and let the filter author write v4-shape config directly.

Workaround for site owners

Until upstream has a fix, site owners on v4 can avoid the error by either:

  • Not registering any mathjax_config filter (the plugin emits nothing if the filter returns empty)
  • Emitting their own window.MathJax = {...} via wp_head instead of the filter

Offer

Happy to submit a PR if that would be useful. Let me know if there's a preferred approach for the v2→v4 config translation (full mapping vs pass-through vs something in between) and I'll match that.

Cheers!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions