diff --git a/CHANGES b/CHANGES
index 81e2ebf64cd..964fdfcd35a 100644
--- a/CHANGES
+++ b/CHANGES
@@ -13,9 +13,15 @@ Deprecated
Features added
--------------
+* #9864: mathjax: Add :confval:`mathjax_loading_method` to change the loading
+ method of mathjax library
+
Bugs fixed
----------
+* #9864: mathjax: Failed to render equations via MathJax v2. The loading method
+ of MathJax is back to "async" strategy again
+
Testing
--------
diff --git a/doc/usage/extensions/math.rst b/doc/usage/extensions/math.rst
index 764bf5dd3ed..82d087d8018 100644
--- a/doc/usage/extensions/math.rst
+++ b/doc/usage/extensions/math.rst
@@ -253,6 +253,15 @@ Sphinx but is set to automatically include it from a third-party site.
This has been renamed to :confval:`mathjax2_config`.
:confval:`mathjax_config` is still supported for backwards compatibility.
+.. confval:: mathjax_loading_method
+
+ The loading method of MathJax library. The available loading methods are:
+
+ * ``'async'`` - load MathJax asynchronous (Default)
+ * ``'defer'`` - load MathJax as deffered
+
+ .. versionadded:: 4.4.1
+
:mod:`sphinx.ext.jsmath` -- Render math via JavaScript
------------------------------------------------------
diff --git a/sphinx/ext/mathjax.py b/sphinx/ext/mathjax.py
index eb06908d30e..c0d77d49e31 100644
--- a/sphinx/ext/mathjax.py
+++ b/sphinx/ext/mathjax.py
@@ -17,6 +17,7 @@
import sphinx
from sphinx.application import Sphinx
+from sphinx.config import ENUM
from sphinx.domains.math import MathDomain
from sphinx.errors import ExtensionError
from sphinx.locale import _
@@ -81,10 +82,10 @@ 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 = {app.config.mathjax_loading_method: app.config.mathjax_loading_method}
if app.config.mathjax_options:
options.update(app.config.mathjax_options)
- app.add_js_file(app.config.mathjax_path, **options) # type: ignore
+ app.add_js_file(app.config.mathjax_path, **options)
if app.config.mathjax2_config:
if app.config.mathjax_path == MATHJAX_URL:
@@ -110,6 +111,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.add_config_value('mathjax_config', None, 'html')
app.add_config_value('mathjax2_config', lambda c: c.mathjax_config, 'html')
app.add_config_value('mathjax3_config', None, 'html')
+ app.add_config_value('mathjax_loading_method', 'async', 'html', ENUM('async', 'defer'))
app.connect('html-page-context', install_mathjax)
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
diff --git a/tests/test_ext_math.py b/tests/test_ext_math.py
index 7c78954b7ff..965ac56a823 100644
--- a/tests/test_ext_math.py
+++ b/tests/test_ext_math.py
@@ -71,11 +71,22 @@ def test_mathjax_options(app, status, warning):
app.builder.build_all()
content = (app.outdir / 'index.html').read_text()
- assert ('' in content)
+@pytest.mark.sphinx('html', testroot='ext-math',
+ confoverrides={'extensions': ['sphinx.ext.mathjax'],
+ 'mathjax_loading_method': 'defer'})
+def test_mathjax_loading_method(app, status, warning):
+ app.builder.build_all()
+
+ content = (app.outdir / 'index.html').read_text()
+ assert ('' in content)
+
+
@pytest.mark.sphinx('html', testroot='ext-math',
confoverrides={'extensions': ['sphinx.ext.mathjax']})
def test_mathjax_align(app, status, warning):