Stop 04 · JavaScriptProjects · 7/8

Infinite Scroll

Part of the Frontend Developer Roadmap

In short

Instagram and YouTube never show a "Next page" button. They load more as you scroll. Building that yourself teaches you pagination, observers and how not to flood a server.

A feed that loads more content automatically as the user scrolls near the bottom — practice for the Intersection Observer API and paginated data fetching. Infinite scrolling also requires careful state management to avoid duplicate requests, race conditions, repeated loading, inaccessible content, and poor scroll performance.

The jaadu mascot eats a thali while a smiling server refills its sambar bowl.

Think of it like this

The thali refill

At a good thali place, the server tops up your sambar the moment your bowl looks low. You never have to ask. Infinite scroll watches the bottom of the page the same way and fetches more just before you run out.

Watch it happen

Loading the next page

Observer
callback
API

sentinel near (200px)

1/7The sentinel comes within 200px of the screen, so the callback fires.

The big ideas

What you need to know

Watch a sentinel

Put an empty div after the list. IntersectionObserver tells you when it scrolls into view, no scroll event needed.

Track the page

Keep a page number and ask the API for the next page each time, like ?_page=2&_limit=10.

Guard against double loads

A loading flag stops a second request starting while the first one is still running.

Know when to stop

When the API returns an empty page, stop observing and show "You're all caught up".

How it works

Build plan

  1. 1

    First page

    Fetch and render the first 10 items on page load.

  2. 2

    Add a sentinel

    An empty div after the list that you'll watch.

  3. 3

    Observe it

    IntersectionObserver calls loadMore when the sentinel is near the screen.

  4. 4

    Append, don't replace

    Add new items to the end and bump the page number.

  5. 5

    Stop and polish

    End message, loading spinner and an error retry button.

See it in code

Walk through the code

js
1let page = 1;2let loading = false;3let done = false;4const sentinel = document.querySelector("#sentinel");5 6const observer = new IntersectionObserver(async ([entry]) => {7  if (!entry.isIntersecting || loading || done) return;8  loading = true;9  const res = await fetch(`https://jsonplaceholder.typicode.com/posts?_page=${page}&_limit=10`);10  const posts = await res.json();11  if (posts.length === 0) { done = true; observer.disconnect(); }12  else { renderPosts(posts); page++; }13  loading = false;14}, { rootMargin: "200px" });15 16observer.observe(sentinel);

1/4Track the page, a loading guard, an end flag and the sentinel.

rootMargin: "200px" starts loading when the sentinel is 200px away from the screen, so new posts are ready before the user hits the bottom.

Save yourself the pain

Common mistakes

Oops

Listening to every scroll event and checking positions by hand.

Do this instead

It fires constantly and is easy to get wrong. IntersectionObserver does the watching for you.

Oops

No loading flag, so fast scrolling fires the same page twice.

Do this instead

Set loading = true before fetching and back to false after, and skip if it's already true.

Oops

Putting important links in a footer below an infinite list.

Do this instead

Users can never reach it. Move them elsewhere or switch to a "Load more" button.

Your mission

Milestone 1: load page two

~40 min

Quick check

What does rootMargin: "200px" do in the observer above?

Go deeper

  1. 1Use the Intersection Observer API to detect when the user nears the bottom. Verify the behavior with realistic data and handle the failure or empty state as well.
  2. 2Show a loading indicator while the next page of data fetches. Validate your understanding by applying it in a small practical example.
  3. 3Handle the 'end of results' state so it doesn't loop or error out.

More projects at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge