From ef988dab4a5a1613a24002eae26dc7b4951795c9 Mon Sep 17 00:00:00 2001 From: RAJVEER42 Date: Mon, 1 Jun 2026 00:24:35 +0530 Subject: [PATCH] fix(ssr): prevent hydration mismatches from client-only storage reads Header called isAuth() and getAllGroups() directly in JSX render. Footer initialized useState with getSessionStorage(). During SSR these return null/false; on the client they return real values, causing React hydration mismatches. Defer all storage reads to useEffect so server and client render the same initial output. Also guard getLocalStorage and getSessionStorage against stored 'undefined' strings, which caused JSON.parse to throw when a key was set with an undefined value. Signed-off-by: RAJVEER42 --- src/components/Footer/Footer.jsx | 9 +++++---- src/components/Header/Header.jsx | 10 +++++++--- src/shared/storageHelper.js | 8 ++++++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/components/Footer/Footer.jsx b/src/components/Footer/Footer.jsx index a5d78c266..d8a6f77e5 100644 --- a/src/components/Footer/Footer.jsx +++ b/src/components/Footer/Footer.jsx @@ -21,9 +21,7 @@ import { getFossologyVersion } from "@/services/info"; import { getSessionStorage, setSessionStorage } from "@/shared/storageHelper"; const Footer = () => { - const [version, setVersion] = useState( - getSessionStorage("fossologyVersion") || null - ); + const [version, setVersion] = useState(null); const fetchVersion = () => { return getFossologyVersion() @@ -36,7 +34,10 @@ const Footer = () => { }; useEffect(() => { - if (!version) { + const cached = getSessionStorage("fossologyVersion"); + if (cached) { + setVersion(cached); + } else { fetchVersion(); } }, []); diff --git a/src/components/Header/Header.jsx b/src/components/Header/Header.jsx index da4db86ec..95027b099 100644 --- a/src/components/Header/Header.jsx +++ b/src/components/Header/Header.jsx @@ -46,6 +46,8 @@ import { getLocalStorage, setLocalStorage } from "@/shared/storageHelper"; export default function Header() { const [currentGroup, setCurrentGroup] = useState(null); + const [authenticated, setAuthenticated] = useState(false); + const [groups, setGroups] = useState(null); const pathname = usePathname(); const router = useRouter(); @@ -78,6 +80,8 @@ export default function Header() { getLocalStorage("currentGroup") || getLocalStorage("user")?.default_group; setCurrentGroup(defaultGroup); + setAuthenticated(isAuth()); + setGroups(getAllGroups()); }, []); const handleGroupChange = (groupName) => { @@ -94,7 +98,7 @@ export default function Header() { {/* Navigation Menu */}