Fiber UI LogoFiberUI

useIsMounted

A hook to detect if a component has mounted on the client

A simple hook that returns true after the component has mounted on the client. Essential for preventing React hydration mismatches when rendering client-only content.

Source Code

View the full hook implementation in the Hook Source Code section below.

Features

  • SSR Safe - Returns false during server-side rendering
  • Hydration Safe - Prevents mismatches between server and client renders
  • Simple API - Just returns a boolean, no configuration needed
  • Zero Dependencies - Uses only React's built-in hooks

Learn More

When to Use

Use useIsMounted when you need to:

  • Access browser APIs - window, document, navigator, etc.
  • Render dynamic content - Content that differs between server and client
  • Prevent hydration warnings - Any scenario where SSR output differs from client
  • Show loading states - Display skeletons until client-side data is available

Performance Note

Using useIsMounted causes an extra render after mount. For simple cases, consider using CSS to hide/show content instead.


Basic Usage

The hook returns false during SSR and true after the component mounts:

Not Mounted (SSR)

This indicator shows green only after the component mounts on the client.

"use client";

import { useIsMounted } from "@repo/hooks/utility/use-is-mounted";

/* BASIC USAGE - Prevent Hydration Mismatch */
export const Example1 = () => {
    const isMounted = useIsMounted();

    return (
        <div className="flex flex-col gap-2">
            <div className="flex items-center gap-2">
                <span
                    className={`h-3 w-3 rounded-full ${
                        isMounted ? "bg-green-500" : "bg-yellow-500"
                    }`}
                />
                <span className="text-sm">
                    {isMounted ? "Mounted (Client)" : "Not Mounted (SSR)"}
                </span>
            </div>
            <p className="text-muted-foreground text-xs">
                This indicator shows green only after the component mounts on
                the client.
            </p>
        </div>
    );
};

Client-Only Content

Perfect for rendering content that depends on browser APIs like window:

Try it out!

This example accesses window.innerWidth, but without the use of useIsMounted hook in SSR environment, this would cause a hydration error!

"use client";

import { useIsMounted } from "@repo/hooks/utility/use-is-mounted";

/* CLIENT-ONLY CONTENT - Window Dimensions */
export const Example2 = () => {
    const isMounted = useIsMounted();

    if (!isMounted) {
        return <div className="bg-muted h-16 w-48 animate-pulse rounded-md" />;
    }

    return (
        <div className="flex flex-col gap-1 rounded-md border p-4">
            <p className="text-sm font-medium">Window Size</p>
            <p className="text-2xl font-bold">
                {window.innerWidth} × {window.innerHeight}
            </p>
            <p className="text-muted-foreground text-xs">
                This would cause a hydration error without useIsMounted
            </p>
        </div>
    );
};

Common Patterns

With Skeleton Loading

const isMounted = useIsMounted();

if (!isMounted) {
    return <Skeleton className="h-10 w-full" />;
}

return <ClientComponent />;

Conditional Rendering

const isMounted = useIsMounted();

return (
    <div>
        <p>This renders on both server and client</p>
        {isMounted && <p>This only renders on client</p>}
    </div>
);

With Browser APIs

const isMounted = useIsMounted();

const userAgent = isMounted ? navigator.userAgent : "Unknown";
const screenWidth = isMounted ? window.innerWidth : 0;

API Reference

function useIsMounted(): boolean;

Returns

TypeDescription
booleanfalse during SSR, true after component mounts

Hook Source Code

import { useState, useEffect } from "react";

/**
 * A simple hook that returns true after the component has mounted.
 * Useful for preventing hydration mismatches in client components.
 *
 * @returns boolean - false during SSR, true after mount
 *
 * @example
 * ```tsx
 * const isMounted = useIsMounted();
 *
 * if (!isMounted) {
 *     return <Skeleton />;
 * }
 *
 * return <ClientOnlyComponent />;
 * ```
 */
export function useIsMounted(): boolean {
    const [isMounted, setIsMounted] = useState(false);

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

    return isMounted;
}

export default useIsMounted;