DeltaKitDeltaKit

useAutoScroll

Hook that keeps a scroll container pinned to the bottom during streaming.

Signature

function useAutoScroll<T extends HTMLElement = HTMLDivElement>(
  dependencies: unknown[],
  options?: UseAutoScrollOptions,
): UseAutoScrollReturn<T>;

Parameters

dependencies

Type: unknown[]

Array of values to watch — auto-scroll triggers when these change. Typically [messages] from useStreamChat.

const { messages } = useStreamChat({ api: "/api/chat" });
const { ref } = useAutoScroll([messages]);

options

Type: UseAutoScrollOptions (optional)

options.behavior

Type: ScrollBehavior — Default: "smooth"

The scroll behavior used by the scrollToBottom() function. During streaming auto-scroll, the hook always uses instant scrollTop updates to avoid flicker. Use "smooth" (default) for an animated scroll-to-bottom, or "instant" to snap without animation.

const { ref, scrollToBottom } = useAutoScroll([messages], { behavior: "smooth" });

options.enabled

Type: boolean — Default: true

Set to false to disable auto-scroll entirely. The ref remains attached but no scroll behavior is applied.

const { ref } = useAutoScroll([messages], { enabled: false });

options.threshold

Type: number — Default: 50

Distance in pixels from the bottom within which the container is considered "at bottom". When the user scrolls up beyond this threshold, or wheels upward during active pinning, auto-scroll pauses. When they scroll back within it, auto-scroll re-engages.

const { ref } = useAutoScroll([messages], { threshold: 100 });

Return Value

ref

Type: RefObject<T | null>

Attach this to your scrollable container element. The container must have a fixed height and overflow-y: auto (or scroll) for scrolling to work.

<div ref={ref} className="h-screen overflow-y-auto">
  {/* scrollable content */}
</div>

scrollToBottom

Type: () => void

Imperatively scroll to the bottom and re-pin auto-scroll. Useful in form submit handlers to ensure the view follows the new response:

const handleSubmit = (text: string) => {
  sendMessage(text);
  scrollToBottom();
};

isAtBottom

Type: boolean

Reactive value that is true when the scroll container is at or near the bottom (within threshold). Use this to conditionally render a "scroll to bottom" indicator:

{!isAtBottom && (
  <button onClick={scrollToBottom}>Scroll to bottom</button>
)}

Generic Type Parameter

The generic T controls the type of the ref. It defaults to HTMLDivElement but can be narrowed to any HTMLElement subtype:

const { ref } = useAutoScroll<HTMLUListElement>([messages]);

return <ul ref={ref}>{/* items */}</ul>;

Behavior

User actionHook behavior
Initial renderPinned to bottom
Content streams in (pinned)Stays at bottom
User scrolls up / wheels upwardAuto-scroll pauses immediately
Content streams in (detached)View stays where user left it
User scrolls back near bottomAuto-scroll re-engages
scrollToBottom() calledForce-scrolls to bottom, re-pins

On this page