A chat that follows new messages only when you're at the bottom
While at the bottom, new messages scroll into view. After scrolling up, two new messages leave the reader alone and show a button instead. The decision is taken in useLayoutEffect, so there's never a visible jump.
Scrolling is part of the UX you build: new pages start at the top, Back returns to where the user was, links and buttons scroll smoothly to the right place below sticky headers, a table of contents highlights the section in view, chats stay pinned to the newest message only when the reader is there, and modals stop the page behind them from scrolling.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 6 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Write a useScrollToTopOnPush(ref) hook for a router app that scrolls a container to the top on PUSH navigations only.
Add a "Back to top" button to a long page that appears after scrolling 400px and respects reduced motion.
Explain it without notes
Why does an SPA need its own scroll restoration, and how would you implement it?
How do you scroll to a section without it ending up under a sticky header?
How would you implement a scroll spy for a table of contents?
Describe the scroll rules a chat window needs.
How do you stop the page from scrolling behind a modal, and what are the gotchas?
Preview
Console
Nothing logged yet.Expected console output
Reading the latest, new message arrives -> at bottom: true
Reading history -> at bottom: false, scrollTop 0, pill: ↓ 2 new messages
After the pill -> at bottom: true, pill shown: false