From 78f44d0ae70fb98a63681b469977e8f074d339da Mon Sep 17 00:00:00 2001
From: Kenneth Ormandy <hello@kennethormandy.com>
Date: Thu, 30 Jan 2025 09:24:33 -0800
Subject: [PATCH] fix(theme): Hide code block buttons before React hydration
 (#10866)

---
 .../src/theme/CodeBlock/Content/String.tsx    | 24 +++++++++++--------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/String.tsx b/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/String.tsx
index 1956455a82fa..fb6c6763dfbd 100644
--- a/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/String.tsx
+++ b/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/String.tsx
@@ -15,6 +15,7 @@ import {
   getLineNumbersStart,
   useCodeWordWrap,
 } from '@docusaurus/theme-common/internal';
+import useIsBrowser from '@docusaurus/useIsBrowser';
 import {Highlight, type Language} from 'prism-react-renderer';
 import Line from '@theme/CodeBlock/Line';
 import CopyButton from '@theme/CodeBlock/CopyButton';
@@ -48,6 +49,7 @@ export default function CodeBlockString({
 
   const prismTheme = usePrismTheme();
   const wordWrap = useCodeWordWrap();
+  const isBrowser = useIsBrowser();
 
   // We still parse the metastring in case we want to support more syntax in the
   // future. Note that MDX doesn't strip quotes when parsing metastring:
@@ -111,16 +113,18 @@ export default function CodeBlockString({
             </pre>
           )}
         </Highlight>
-        <div className={styles.buttonGroup}>
-          {(wordWrap.isEnabled || wordWrap.isCodeScrollable) && (
-            <WordWrapButton
-              className={styles.codeButton}
-              onClick={() => wordWrap.toggle()}
-              isEnabled={wordWrap.isEnabled}
-            />
-          )}
-          <CopyButton className={styles.codeButton} code={code} />
-        </div>
+        {isBrowser ? (
+          <div className={styles.buttonGroup}>
+            {(wordWrap.isEnabled || wordWrap.isCodeScrollable) && (
+              <WordWrapButton
+                className={styles.codeButton}
+                onClick={() => wordWrap.toggle()}
+                isEnabled={wordWrap.isEnabled}
+              />
+            )}
+            <CopyButton className={styles.codeButton} code={code} />
+          </div>
+        ) : null}
       </div>
     </Container>
   );