How to fix Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. in React

ReactINTERMEDIATEMEDIUMUpdated Dec 8, 2025ยท 132 views

This warning appears during server-side rendering when React encounters useLayoutEffect in a component. Since there is no DOM on the server, layout effects cannot run, which will cause a mismatch between server and client rendering.

Quick fix

Fixes Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI.

// Before
import { useLayoutEffect } from 'react';

function MyComponent() {
  useLayoutEffect(() => {
    console.log('Component mounted');
  }, []);
}

// After
import { useEffect } from 'react';

function MyComponent() {
  useEffect(() => {
    console.log('Component mounted');
  }, []);
}
  1. Replace useLayoutEffect with useEffect for non-critical updates
  2. Create a useIsomorphicLayoutEffect hook for environment-aware effects
  3. Defer component rendering until after hydration
  4. Mark components as client-only with dynamic imports
react โ€” error
// Before
import { useLayoutEffect } from 'react';
function MyComponent() {
useLayoutEffect(() => {
console.log('Component mounted');
}, []);
}
// After
import { useEffect } from 'react';
function MyComponent() {
useEffect(() => {
console.log('Component mounted');
}, []);
}
Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI.

What this error means

This warning occurs when you use useLayoutEffect in a component that is being rendered on the server (SSR/SSG). The useLayoutEffect hook is designed to run synchronously after all DOM mutations but before the browser paints, allowing you to measure layout and synchronously re-render. However, during server-side rendering, there is no actual DOM to measure or manipulate. React emits this warning specifically for useLayoutEffect (not useEffect) because useLayoutEffect is typically used to perform DOM measurements or manipulations before the user sees the rendered component. When the server-rendered HTML reaches the browser, React will hydrate it and run the useLayoutEffect for the first time, potentially causing a visual jump or mismatch if the effect changes what the user sees. The warning indicates that your component's initial server-rendered output may not match what the client renders after hydration, leading to potential layout shifts, visual inconsistencies, or hydration errors.

Typical symptoms

  • Console warning appears during server-side rendering or static generation
  • Component renders differently on initial server load versus after hydration
  • Visual content "jumps" or shifts position after page loads
  • Hydration mismatch errors in development mode
  • Warning appears in Next.js builds during `next build` or `next dev`
  • Components using third-party libraries that internally use useLayoutEffect show warnings
  • Warning appears when using hooks like react-redux's useSelector or react-hook-form in SSR apps

Common causes

  1. Using useLayoutEffect directly in a component that renders on the server
  2. Third-party libraries (react-redux, framer-motion, react-dnd, react-hook-form) using useLayoutEffect internally
  3. Measuring DOM elements (getBoundingClientRect, offsetWidth, scrollHeight) inside useLayoutEffect during SSR
  4. Manipulating DOM nodes or reading layout properties before first paint in SSR context
  5. Not distinguishing between server and client rendering environments in hook logic
  6. Using useLayoutEffect to set state based on window dimensions or browser APIs
  7. Component libraries that depend on layout measurements (tooltips, popovers, drag-and-drop)
  8. Migrating from client-only React app to Next.js or other SSR framework without updating hooks

How to fix "Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI."

1Replace useLayoutEffect with useEffect for non-critical updates

If your effect doesn't need to run before the browser paints (e.g., logging, data fetching, subscriptions), replace useLayoutEffect with useEffect:

tsx
// Before
import { useLayoutEffect } from 'react';

function MyComponent() {
  useLayoutEffect(() => {
    console.log('Component mounted');
  }, []);
}

// After
import { useEffect } from 'react';

function MyComponent() {
  useEffect(() => {
    console.log('Component mounted');
  }, []);
}

useEffect runs asynchronously after the paint, preventing the server warning and avoiding blocking the initial render.

2Create a useIsomorphicLayoutEffect hook for environment-aware effects

Create a custom hook that uses useEffect on the server and useLayoutEffect on the client:

tsx
// lib/hooks/useIsomorphicLayoutEffect.ts
import { useEffect, useLayoutEffect } from 'react';

const useIsomorphicLayoutEffect =
  typeof window !== 'undefined' ? useLayoutEffect : useEffect;

export default useIsomorphicLayoutEffect;

Then use it in your components:

tsx
import useIsomorphicLayoutEffect from '@/lib/hooks/useIsomorphicLayoutEffect';

function MyComponent() {
  useIsomorphicLayoutEffect(() => {
    // This runs as useLayoutEffect on client, useEffect on server
    const element = document.getElementById('my-element');
    const height = element?.offsetHeight;
    // ...
  }, []);
}

This pattern is used by major libraries like react-redux and react-beautiful-dnd.

3Defer component rendering until after hydration

For components that absolutely need layout effects, render them only after the client has hydrated:

tsx
import { useEffect, useState, useLayoutEffect } from 'react';

function MyComponent() {
  const [isClient, setIsClient] = useState(false);

  useEffect(() => {
    setIsClient(true);
  }, []);

  useLayoutEffect(() => {
    if (!isClient) return;
    // Safe to use layout effect now
    const rect = element.getBoundingClientRect();
    // ...
  }, [isClient]);

  if (!isClient) {
    return <div>Loading...</div>; // Fallback for SSR
  }

  return <div>{/* Actual content */}</div>;
}

This ensures the server renders a fallback while the client renders the full component with layout effects.

4Mark components as client-only with dynamic imports

In Next.js, use dynamic imports with ssr: false to prevent server-side rendering:

tsx
// app/page.tsx
import dynamic from 'next/dynamic';

const ClientOnlyComponent = dynamic(
  () => import('@/components/ClientOnlyComponent'),
  { ssr: false }
);

export default function Page() {
  return (
    <div>
      <h1>My Page</h1>
      <ClientOnlyComponent />
    </div>
  );
}

In the component:

tsx
// components/ClientOnlyComponent.tsx
import { useLayoutEffect, useState } from 'react';

export default function ClientOnlyComponent() {
  const [dimensions, setDimensions] = useState({ width: 0, height: 0 });

  useLayoutEffect(() => {
    // No warning - this only runs on client
    setDimensions({
      width: window.innerWidth,
      height: window.innerHeight
    });
  }, []);

  return <div>Window: {dimensions.width}x{dimensions.height}</div>;
}
5Suppress warnings for third-party libraries

If the warning comes from a library you cannot modify, you can suppress it using React's DevTools or by patching the library. However, first check if the library has an SSR-compatible version or configuration.

For Next.js, you can suppress specific warnings in next.config.js:

js
// next.config.js
module.exports = {
  webpack: (config, { isServer }) => {
    if (!isServer) {
      // Suppress client-side warnings
      config.resolve.fallback = {
        ...config.resolve.fallback,
      };
    }
    return config;
  },
};

Or update the library if a newer version fixes SSR compatibility (common with react-redux 7.1+, framer-motion, etc.).

6Use Suspense boundaries for gradual hydration

Wrap components using layout effects in Suspense boundaries to defer their rendering until client hydration:

tsx
import { Suspense } from 'react';

function Page() {
  return (
    <div>
      <h1>Content above suspense renders immediately</h1>
      <Suspense fallback={<div>Loading interactive content...</div>}>
        <ComponentWithLayoutEffect />
      </Suspense>
    </div>
  );
}

This allows the server to render a fallback while the component with layout effects only renders on the client after hydration.

Advanced notes

Why React warns only for useLayoutEffect: While both useEffect and useLayoutEffect cannot affect server-rendered output, React specifically warns about useLayoutEffect because it typically modifies the DOM before paint. Using it during SSR creates an unavoidable mismatch - the server has no DOM to measure, but the client will measure and potentially re-render before the user sees anything, causing layout shifts.

Performance considerations: useLayoutEffect blocks the browser from painting until the effect completes. On the server, this doesn't matter (no browser), but on the client, it can delay time-to-first-paint. Only use useLayoutEffect when you must prevent visual flashing (e.g., tooltip positioning, DOM measurements for animations). For most cases, useEffect is sufficient.

React 18 and Suspense: In React 18, Suspense handles client-only rendering more gracefully. You can mark components as client-only by placing them inside Suspense boundaries, and React will skip server rendering them automatically.

Popular library patterns: Libraries like react-redux (v7.1+), framer-motion (v6+), and react-beautiful-dnd have adopted useIsomorphicLayoutEffect internally to prevent this warning. If you see warnings from these libraries, update to the latest version first.

Next.js specific: Next.js 13+ with app router uses Server Components by default, which never run client hooks. Add "use client" at the top of files using useLayoutEffect, and Next.js will handle client-only rendering automatically.

Frequently asked questions

What does "Warning: useLayoutEffect does nothing on the server, because its effec" mean?
This warning occurs when you use useLayoutEffect in a component that is being rendered on the server (SSR/SSG). The useLayoutEffect hook is designed to run synchronously after all DOM mutations but before the browser paints, allowing you to measure layout and synchronously re-render. However, during server-side rendering, there is no actual DOM to measure or manipulate.
How do I fix "Warning: useLayoutEffect does nothing on the server, because its effec"?
This warning appears during server-side rendering when React encounters useLayoutEffect in a component. Since there is no DOM on the server, layout effects cannot run, which will cause a mismatch between server and client rendering.
What causes "Warning: useLayoutEffect does nothing on the server, because its effec"?
Using useLayoutEffect directly in a component that renders on the server Third-party libraries (react-redux, framer-motion, react-dnd, react-hook-form) using useLayoutEffect internally Measuring DOM elements (getBoundingClientRect, offsetWidth, scrollHeight) inside useLayoutEffect during SSR
Is the "Warning: useLayoutEffect does nothing on the server, because its effec" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading