useIsomorphicLayoutEffect
React hook that uses useLayoutEffect in browser and useEffect during SSR to prevent hydration warnings. Perfect for React applications requiring DOM measurements with Next.js integration and TypeScript support.
Installation
npx shadcn@latest add https://www.shadcn.io/registry/use-isomorphic-layout-effect.json
npx shadcn@latest add https://www.shadcn.io/registry/use-isomorphic-layout-effect.json
pnpm dlx shadcn@latest add https://www.shadcn.io/registry/use-isomorphic-layout-effect.json
bunx shadcn@latest add https://www.shadcn.io/registry/use-isomorphic-layout-effect.json
Features
- SSR-safe implementation with automatic environment detection for server/client rendering
- Hydration warning prevention by using appropriate effect hook based on execution context
- Synchronous DOM access using useLayoutEffect in browser for performance optimization
- Zero runtime overhead with compile-time environment detection for optimal performance
- TypeScript support with complete type definitions matching React's effect hooks
- Drop-in replacement for useLayoutEffect with automatic SSR compatibility
Usage
import { useIsomorphicLayoutEffect } from '@repo/use-isomorphic-layout-effect';
import { useState, useRef } from 'react';
function Component() {
const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
const elementRef = useRef<HTMLDivElement>(null);
useIsomorphicLayoutEffect(() => {
// This runs as useLayoutEffect in browser, useEffect during SSR
if (elementRef.current) {
const rect = elementRef.current.getBoundingClientRect();
setDimensions({
width: rect.width,
height: rect.height
});
}
}, []);
return (
<div ref={elementRef}>
{dimensions.width}x{dimensions.height}
</div>
);
}
API Reference
useIsomorphicLayoutEffect(effect, deps?)
Same API as React's useEffect
and useLayoutEffect
:
- effect:
() => void | (() => void)
- The effect function to run - deps:
DependencyList?
- Optional dependency array
Returns: void
Use Cases
DOM Measurements
Perfect for measuring DOM elements without causing layout shift:
useIsomorphicLayoutEffect(() => {
if (elementRef.current) {
const { width, height } = elementRef.current.getBoundingClientRect();
setDimensions({ width, height });
}
}, []);
Animation Setup
Set up animations that need to run before the browser paints:
useIsomorphicLayoutEffect(() => {
// Set initial animation state before paint
if (elementRef.current) {
elementRef.current.style.transform = 'translateX(-100%)';
}
}, []);
Theme Initialization
Apply theme changes synchronously to prevent flash:
useIsomorphicLayoutEffect(() => {
document.documentElement.classList.add(theme);
}, [theme]);
Implementation Notes
- Browser Environment: Uses
useLayoutEffect
for synchronous DOM reads/writes - Server Environment: Uses
useEffect
to avoid hydration mismatches - Hydration Safety: Prevents "useLayoutEffect does nothing on the server" warnings
- Performance: No runtime overhead - decision made at module evaluation time
Why Use This Hook?
React's useLayoutEffect
throws warnings during SSR because it runs synchronously and can't access the DOM on the server. This hook automatically chooses the right effect hook based on the environment:
- Browser:
useLayoutEffect
- runs synchronously after all DOM mutations - Server:
useEffect
- runs after render, preventing hydration warnings
This is especially useful when you need to:
- Measure DOM elements
- Set up animations
- Apply theme changes
- Perform any DOM manipulation that should happen before paint
useIsMounted
Prevent memory leaks by checking component mount state before async operations. Perfect for React applications requiring safe state updates with Next.js integration and TypeScript support.
useLocalStorage
React hook that uses the localStorage API to persist state across page reloads with automatic serialization and deserialization.