diff --git a/CHANGES b/CHANGES
index 1aaf8210d86..6ef683b8e7a 100644
--- a/CHANGES
+++ b/CHANGES
@@ -13,6 +13,9 @@ Deprecated
Features added
--------------
+* #9864: mathjax: Support chnaging the loading method of MathJax to "defer" via
+ :confval:`mathjax_options`
+
Bugs fixed
----------
@@ -22,6 +25,8 @@ Bugs fixed
having invalid __doc__ atribute
* #9872: html: Class namespace collision between autodoc signatures and
docutils-0.17
+* #9864: mathjax: Failed to render equations via MathJax v2. The loading method
+ of MathJax is back to "async" method again
Testing
--------
diff --git a/doc/usage/extensions/math.rst b/doc/usage/extensions/math.rst
index 764bf5dd3ed..62630608993 100644
--- a/doc/usage/extensions/math.rst
+++ b/doc/usage/extensions/math.rst
@@ -200,6 +200,11 @@ Sphinx but is set to automatically include it from a third-party site.
.. versionadded:: 1.8
+ .. versionchanged:: 4.4.1
+
+ Allow to change the loading method (async or defer) of MathJax if "async"
+ or "defer" key is set.
+
.. confval:: mathjax3_config
The configuration options for MathJax v3 (which is used by default).
diff --git a/sphinx/ext/mathjax.py b/sphinx/ext/mathjax.py
index eb06908d30e..3d545e79b88 100644
--- a/sphinx/ext/mathjax.py
+++ b/sphinx/ext/mathjax.py
@@ -81,10 +81,17 @@ def install_mathjax(app: Sphinx, pagename: str, templatename: str, context: Dict
domain = cast(MathDomain, app.env.get_domain('math'))
if app.registry.html_assets_policy == 'always' or domain.has_equations(pagename):
# Enable mathjax only if equations exists
- options = {'defer': 'defer'}
+ options = {}
if app.config.mathjax_options:
options.update(app.config.mathjax_options)
- app.add_js_file(app.config.mathjax_path, **options) # type: ignore
+ if 'async' not in options and 'defer' not in options:
+ if app.config.mathjax3_config:
+ # Load MathJax v3 via "defer" method
+ options['defer'] = 'defer'
+ else:
+ # Load other MathJax via "async" method
+ options['async'] = 'async'
+ app.add_js_file(app.config.mathjax_path, **options)
if app.config.mathjax2_config:
if app.config.mathjax_path == MATHJAX_URL:
diff --git a/tests/test_ext_math.py b/tests/test_ext_math.py
index 7c78954b7ff..175c9e0f569 100644
--- a/tests/test_ext_math.py
+++ b/tests/test_ext_math.py
@@ -71,7 +71,7 @@ def test_mathjax_options(app, status, warning):
app.builder.build_all()
content = (app.outdir / 'index.html').read_text()
- assert ('' in content)
@@ -221,6 +221,7 @@ def test_mathjax3_config(app, status, warning):
content = (app.outdir / 'index.html').read_text()
assert MATHJAX_URL in content
+ assert ('' in content)
@@ -231,12 +232,35 @@ def test_mathjax2_config(app, status, warning):
app.builder.build_all()
content = (app.outdir / 'index.html').read_text()
- assert MATHJAX_URL in content
+ assert ('' in content)
+@pytest.mark.sphinx('html', testroot='ext-math',
+ confoverrides={'extensions': ['sphinx.ext.mathjax'],
+ 'mathjax_options': {'async': 'async'},
+ 'mathjax3_config': {'extensions': ['tex2jax.js']}})
+def test_mathjax_options_async_for_mathjax3(app, status, warning):
+ app.builder.build_all()
+
+ content = (app.outdir / 'index.html').read_text()
+ assert MATHJAX_URL in content
+ assert ('