From 05d58025c452811022a27abb4276094d119dbdbf Mon Sep 17 00:00:00 2001 From: Dayuan Jiang <34411969+DayuanJiang@users.noreply.github.com> Date: Sun, 7 Dec 2025 00:45:19 +0900 Subject: [PATCH] fix: fix hydration mismatch for DrawIO theme loading (#131) - Load DrawIO theme from localStorage after mount with useEffect - Add loading spinner while theme loads - Prevents SSR/client hydration mismatch (server has no localStorage) Co-authored-by: dayuan.jiang --- app/page.tsx | 60 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index 2fca1b9..3fd58b2 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -15,20 +15,26 @@ export default function Home() { const { drawioRef, handleDiagramExport } = useDiagram() const [isMobile, setIsMobile] = useState(false) const [isChatVisible, setIsChatVisible] = useState(true) - const [drawioUi, setDrawioUi] = useState<"min" | "sketch">(() => { - if (typeof window !== "undefined") { - const saved = localStorage.getItem("drawio-theme") - if (saved === "min" || saved === "sketch") return saved + const [drawioUi, setDrawioUi] = useState<"min" | "sketch">("min") + const [isThemeLoaded, setIsThemeLoaded] = useState(false) + + // Load theme from localStorage after mount to avoid hydration mismatch + useEffect(() => { + const saved = localStorage.getItem("drawio-theme") + if (saved === "min" || saved === "sketch") { + setDrawioUi(saved) } - return "min" - }) - const [closeProtection, setCloseProtection] = useState(() => { - if (typeof window !== "undefined") { - const saved = localStorage.getItem(STORAGE_CLOSE_PROTECTION_KEY) - return saved !== "false" // Default to true + setIsThemeLoaded(true) + }, []) + const [closeProtection, setCloseProtection] = useState(true) + + // Load close protection setting from localStorage after mount + useEffect(() => { + const saved = localStorage.getItem(STORAGE_CLOSE_PROTECTION_KEY) + if (saved === "false") { + setCloseProtection(false) } - return true - }) + }, []) const chatPanelRef = useRef(null) useEffect(() => { @@ -96,18 +102,24 @@ export default function Home() { }`} >
- + {isThemeLoaded ? ( + + ) : ( +
+
+
+ )}