Text to Image (uses useLocalStorage for form data)
Image to Image (uses useLocalStorage for form data)
Upscaler (uses useLocalStorage for form data)
Fix Needed:
Add proper SSR handling with useEffect to ensure localStorage is only accessed on client-side after hydration.
React hydration error occurs on page load:
```
Uncaught Error: Minified React error #418
```
**Error Details:**
React error #418 is a hydration mismatch - server-rendered HTML doesn't match client-side rendering.
**Root Cause:**
The `useLocalStorage` hook accesses `window.localStorage` during initial render, which:
1. Returns different values on server (no localStorage) vs client
2. Causes hydration mismatch
3. Results in error #418
**Impact:**
- Console errors on every page load
- Potential rendering issues
- Breaks React's hydration process
**Pages Affected:**
- Text to Image (uses useLocalStorage for form data)
- Image to Image (uses useLocalStorage for form data)
- Upscaler (uses useLocalStorage for form data)
**Fix Needed:**
Add proper SSR handling with `useEffect` to ensure localStorage is only accessed on client-side after hydration.
Root Cause Analysis:
The useLocalStorage hook was accessing window.localStorage during the initial render phase (inside the useState initializer). This caused a React hydration mismatch because:
Server-side: Renders with initialValue (no localStorage available)
Client-side: Hydrates and immediately reads from localStorage (different value)
Even with the typeof window check, this still caused hydration issues in Next.js.
The Solution:
Implemented the standard SSR-safe localStorage pattern:
// Always start with initialValue (same on server and client)
const [storedValue, setStoredValue] = useState<T>(initialValue);
// Load from localStorage AFTER hydration (client-side only)
useEffect(() => {
try {
const item = window.localStorage.getItem(key);
if (item) {
setStoredValue(JSON.parse(item));
}
} catch (error) {
console.warn(`Error loading localStorage key "${key}":`, error);
}
}, [key]);
Why This Works:
Both server and client render with initialValue initially
After hydration completes, useEffect runs (client-side only)
localStorage value is loaded and state updates
No hydration mismatch, no errors
Changes:
Modified webui/lib/hooks.ts
Changed from useState initializer to useEffect pattern
Reduced code complexity by 2 lines
Result:
✅ No more React error #418
✅ Form data persistence still works correctly
✅ Clean console, no warnings
✅ Smooth page loads
✅ Proper SSR support
The fix is now live and affects all pages using form persistence (text2img, img2img, upscaler).
## Fixed in commit 614f2b0
**Root Cause Analysis:**
The `useLocalStorage` hook was accessing `window.localStorage` during the initial render phase (inside the `useState` initializer). This caused a React hydration mismatch because:
1. **Server-side:** Renders with `initialValue` (no localStorage available)
2. **Client-side:** Hydrates and immediately reads from localStorage (different value)
3. **React:** Detects the mismatch and throws error #418
**The Problem Code:**
```typescript
const [storedValue, setStoredValue] = useState<T>(() => {
if (typeof window === 'undefined') {
return initialValue;
}
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue; // Different on client!
});
```
Even with the `typeof window` check, this still caused hydration issues in Next.js.
**The Solution:**
Implemented the standard SSR-safe localStorage pattern:
```typescript
// Always start with initialValue (same on server and client)
const [storedValue, setStoredValue] = useState<T>(initialValue);
// Load from localStorage AFTER hydration (client-side only)
useEffect(() => {
try {
const item = window.localStorage.getItem(key);
if (item) {
setStoredValue(JSON.parse(item));
}
} catch (error) {
console.warn(`Error loading localStorage key "${key}":`, error);
}
}, [key]);
```
**Why This Works:**
1. Both server and client render with `initialValue` initially
2. After hydration completes, `useEffect` runs (client-side only)
3. localStorage value is loaded and state updates
4. No hydration mismatch, no errors
**Changes:**
- Modified `webui/lib/hooks.ts`
- Changed from `useState` initializer to `useEffect` pattern
- Reduced code complexity by 2 lines
**Result:**
✅ No more React error #418
✅ Form data persistence still works correctly
✅ Clean console, no warnings
✅ Smooth page loads
✅ Proper SSR support
The fix is now live and affects all pages using form persistence (text2img, img2img, upscaler).
React hydration error occurs on page load:
Error Details: React error #418 is a hydration mismatch - server-rendered HTML doesn't match client-side rendering.
Root Cause: The
useLocalStoragehook accesseswindow.localStorageduring initial render, which:Impact:
Pages Affected:
Fix Needed: Add proper SSR handling with
useEffectto ensure localStorage is only accessed on client-side after hydration.Fixed in commit
614f2b0Root Cause Analysis: The
useLocalStoragehook was accessingwindow.localStorageduring the initial render phase (inside theuseStateinitializer). This caused a React hydration mismatch because:initialValue(no localStorage available)The Problem Code:
Even with the
typeof windowcheck, this still caused hydration issues in Next.js.The Solution: Implemented the standard SSR-safe localStorage pattern:
Why This Works:
initialValueinitiallyuseEffectruns (client-side only)Changes:
webui/lib/hooks.tsuseStateinitializer touseEffectpatternResult: ✅ No more React error #418
✅ Form data persistence still works correctly
✅ Clean console, no warnings
✅ Smooth page loads
✅ Proper SSR support
The fix is now live and affects all pages using form persistence (text2img, img2img, upscaler).