diff --git a/web_src/js/markup/mermaid.js b/web_src/js/markup/mermaid.js
index e420ff12a2..cf69739fee 100644
--- a/web_src/js/markup/mermaid.js
+++ b/web_src/js/markup/mermaid.js
@@ -57,16 +57,12 @@ export async function renderMermaid() {
       mermaidBlock.append(btn);
 
       const updateIframeHeight = () => {
-        iframe.style.height = `${iframe.contentWindow.document.body.clientHeight}px`;
+        const body = iframe.contentWindow?.document?.body;
+        if (body) {
+          iframe.style.height = `${body.clientHeight}px`;
+        }
       };
 
-      // update height when element's visibility state changes, for example when the diagram is inside
-      // a <details> + <summary> block and the <details> block becomes visible upon user interaction, it
-      // would initially set a incorrect height and the correct height is set during this callback.
-      (new IntersectionObserver(() => {
-        updateIframeHeight();
-      }, {root: document.documentElement})).observe(iframe);
-
       iframe.addEventListener('load', () => {
         pre.replaceWith(mermaidBlock);
         mermaidBlock.classList.remove('tw-hidden');
@@ -75,6 +71,13 @@ export async function renderMermaid() {
           mermaidBlock.classList.remove('is-loading');
           iframe.classList.remove('tw-invisible');
         }, 0);
+
+        // update height when element's visibility state changes, for example when the diagram is inside
+        // a <details> + <summary> block and the <details> block becomes visible upon user interaction, it
+        // would initially set a incorrect height and the correct height is set during this callback.
+        (new IntersectionObserver(() => {
+          updateIframeHeight();
+        }, {root: document.documentElement})).observe(iframe);
       });
 
       document.body.append(mermaidBlock);