# useStickToBottom

> A React hook that keeps a chat, a log or streaming output pinned to its bottom while it grows, and lets go when the reader scrolls up.

- Type: React hook (Hooks & Utilities)
- Access: Pro (the source needs a Wingo UI Pro plan, see https://wingo-ui.com/pricing)
- Version: 1.0.0
- Install: `npx wingo-ui@latest add use-stick-to-bottom`
- Docs: https://wingo-ui.com/components/use-stick-to-bottom

## Interaction

The demo plays a conversation whose answers stream in word by word, and the panel follows them down. Scroll up with the wheel, a finger or the keys while an answer is still arriving: following stops at once (isFollowing turns off), the text keeps growing below and a New messages button appears. Tap it, or scroll back to the end, and it follows again. Pause stops the script.

## Installation

```bash
npx wingo-ui@latest add use-stick-to-bottom
```

Pro item: run `npx wingo-ui@latest login` once with a Pro account. The CLI adds the files, their dependencies and a version record for updates.

With shadcn: `npx shadcn@latest add @wingo-ui/use-stick-to-bottom` (needs the @wingo-ui registry with your API key in components.json)

Files:

- `hooks/use-stick-to-bottom.ts`

Wingo UI dependencies (installed automatically):

- [Motion presets](https://wingo-ui.com/components/motion) ([Markdown](https://wingo-ui.com/components/motion.md))

## Usage

```tsx
"use client"

import { useStickToBottom } from "@/hooks/use-stick-to-bottom"
import { Button } from "@/components/ui/button"

export function Conversation({ messages }: { messages: { id: string; text: string }[] }) {
  const { scrollRef, contentRef, isAtBottom, scrollToBottom } = useStickToBottom()

  return (
    <div className="relative h-96">
      <div ref={scrollRef} className="h-full overflow-y-auto overscroll-contain">
        <div ref={contentRef} className="flex flex-col gap-3 p-4">
          {messages.map((m) => <p key={m.id}>{m.text}</p>)}
        </div>
      </div>
      {!isAtBottom && (
        <Button size="sm" radius="full" className="absolute bottom-3 left-1/2 -translate-x-1/2" onClick={() => scrollToBottom()}>
          New messages
        </Button>
      )}
    </div>
  )
}
```

## API

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `enabled?` | `boolean` | `true` | useStickToBottom(options?): follow new content while the reader is at the bottom. false never scrolls by itself (scrollToBottom still works). |
| `threshold?` | `number` | `72` | Distance in px from the bottom that still counts as at the bottom: isAtBottom, and where scrolling back down re-sticks. |
| `initial?` | `"instant" \| "smooth" \| false` | `"instant"` | How to reach the bottom when the scroller attaches (opening a conversation). false starts at the top and does not follow until the reader scrolls down. |
| `resize?` | `"smooth" \| "instant"` | `"smooth"` | How to follow content that grows while stuck: smooth eases toward a bottom that is re-read every frame, so a streaming answer glides; instant jumps. Reduced motion always jumps. |
| `returns?` | `{ scrollRef; contentRef; isAtBottom: boolean; isFollowing: boolean; scrollToBottom(behavior?): void; stopFollowing(): void }` |  | scrollRef goes on the overflow-y-auto element, contentRef on the element inside it that grows (defaults to the first child). isAtBottom and isFollowing re-render only when they flip: show a jump-to-latest button while !isAtBottom. scrollToBottom scrolls down and follows again (call it after sending a message); stopFollowing lets go without scrolling. |

## Examples

- **Live log tail**: A new line every 700ms. The view follows the newest one; scroll up to read and a Jump to latest button appears.

## See also

- [useScrollEdges](https://wingo-ui.com/components/use-scroll-edges) ([Markdown](https://wingo-ui.com/components/use-scroll-edges.md))
- [useScrollState](https://wingo-ui.com/components/use-scroll-state) ([Markdown](https://wingo-ui.com/components/use-scroll-state.md))
- [Scroll Area](https://wingo-ui.com/components/scroll-area) ([Markdown](https://wingo-ui.com/components/scroll-area.md))
- [Back To Top](https://wingo-ui.com/components/back-to-top) ([Markdown](https://wingo-ui.com/components/back-to-top.md))

---

Canonical: https://wingo-ui.com/components/use-stick-to-bottom
More components: https://wingo-ui.com/components · Index for agents: https://wingo-ui.com/llms.txt
