Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/CardGeneratorModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export default function CardGeneratorModal({
toggleMainBlockVisibility,
toggleDisplayOption,
isBlockVisible,
} = useCardSettings(mounted);
} = useCardSettings();

const {
isGenerating,
Expand Down
27 changes: 3 additions & 24 deletions src/hooks/useCardSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,16 @@ import {
} from "@/lib/cardSettings";
import type { CardLayout, CardBlockId } from "@/lib/types";

export function useCardSettings(mounted: boolean) {
const [isHydrated, setIsHydrated] = useState(false);
export function useCardSettings() {
const [layout, setLayout] = useState<CardLayout>(() => loadCardSettings().layout);
const [displayOptions, setDisplayOptions] = useState<CardDisplayOptions>(
() => loadCardSettings().options,
);

// Initialize state from storage on mount
// Persist changes to storage
useEffect(() => {
if (!mounted || isHydrated) {
return;
}

const { layout: storedLayout, options: storedOptions } = loadCardSettings();

// eslint-disable-next-line react-hooks/set-state-in-effect
setLayout((prev) => JSON.stringify(prev) !== JSON.stringify(storedLayout) ? storedLayout : prev);
// eslint-disable-next-line react-hooks/set-state-in-effect
setDisplayOptions((prev) => JSON.stringify(prev) !== JSON.stringify(storedOptions) ? storedOptions : prev);

setIsHydrated(true);
}, [mounted, isHydrated]);

// Persist changes to storage
useEffect(() => {
if (!mounted || !isHydrated) {
return;
}

saveCardSettings(layout, displayOptions);
}, [layout, displayOptions, mounted, isHydrated]);
}, [layout, displayOptions]);
Comment on lines 19 to +21

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Hydration Defaults Overwrite Storage

SSR initializes this hook with default settings because window is unavailable, and this effect now saves those defaults as soon as the client hydrates. Since CardGeneratorModal calls the hook before returning null, an existing localStorage customization can be overwritten before the user opens the modal.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/hooks/useCardSettings.ts
Line: 19-21

Comment:
**Hydration Defaults Overwrite Storage**

SSR initializes this hook with default settings because `window` is unavailable, and this effect now saves those defaults as soon as the client hydrates. Since `CardGeneratorModal` calls the hook before returning `null`, an existing localStorage customization can be overwritten before the user opens the modal.

How can I resolve this? If you propose a fix, please make it concise.


const toggleMainBlockVisibility = useCallback((blockId: CardBlockId) => {
setLayout((prev) => toggleBlockVisibility(prev, blockId));
Expand Down
Loading