Join our Discord Community

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.

Loading component...

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