Skip to main content
useClickOutside calls a handler when pointer interactions happen outside the tracked element or outside a provided list of elements.

Usage

import { useClickOutside } from '@kuzenbo/hooks';
import { useState } from 'react';

function Demo() {
  const [visible, setVisible] = useState(false);
  const ref = useClickOutside<HTMLDivElement>(() => {
    console.log('clicked outside');
    setVisible(false);
  });

  return (
    <div>
      {visible && (
        <div ref={ref} style={{ padding: 40, background: 'orange' }}>
          Click outside this box
        </div>
      )}
      <button onClick={() => setVisible(true)}>Show box</button>
    </div>
  );
}

API Reference

Parameters

onOutsideClick
(event: MouseEvent | TouchEvent) => void
required
Callback invoked for outside mousedown or touchstart events.
events
string[] | null
default:"['mousedown', 'touchstart']"
Document event names to listen to. Pass null to use the default events.
nodes
(HTMLElement | null)[]
Optional list of elements to treat as “inside”. When provided, these nodes are checked instead of the returned ref.

Returns

ref
RefObject<T>
A ref object to attach to the element you want to track clicks outside of.

Multiple Elements

You can provide multiple elements to treat as “inside” using the nodes parameter:
import { useClickOutside } from '@kuzenbo/hooks';
import { useRef } from 'react';

function Demo() {
  const buttonRef = useRef<HTMLButtonElement>(null);
  const dropdownRef = useRef<HTMLDivElement>(null);

  useClickOutside(
    () => console.log('clicked outside both elements'),
    null,
    [buttonRef.current, dropdownRef.current]
  );

  return (
    <>
      <button ref={buttonRef}>Toggle</button>
      <div ref={dropdownRef}>Dropdown content</div>
    </>
  );
}

Custom Events

Customize which events trigger the outside click handler:
import { useClickOutside } from '@kuzenbo/hooks';

function Demo() {
  const ref = useClickOutside(
    () => console.log('clicked outside'),
    ['mousedown'] // Only listen to mousedown, not touchstart
  );

  return <div ref={ref}>Content</div>;
}

Build docs developers (and LLMs) love