← Blog

Understanding Partial Prerendering in Next.js 15

Aug 6, 2025 by Florian

Featured image

The release of Next.js 15 introduced a new experimental feature called Partial Prerendering (PPR).

When I read about it on Twitter, I was always confused. What does PPR actually do?

Well, while preparing my updated Next.js 16 course, I played around with PPR and came up with a simple example that I want to show you:

Partial Prerendering Example

Look at this page that renders a single blog post:

A blog post page with a dropdown menu in the navbar that shows the current user session (email + signout button)

This page is a perfect candidate for static caching. A blog post doesn't change often, so there is no need to fetch it from the database every time a user visits the page.

Instead, we can fetch the post once at compile-time, render static HTML, and then serve this page from the cache to every user. Next.js can do this out of the box.

The problem is the dropdown menu in the navbar that shows the currently logged-in user (red box in the image above).

In order to fetch the current user, we have to access the cookies() function (auth libraries do this under the hood). But calling cookies() opts out the whole page of static caching. This makes sense, tho, because depending on who visits the page, we need to show different user data in that dropdown menu.

This is where Partial Prerendering comes in:

PPR allows us to wrap the dynamic part (the dropdown menu) into a Suspense boundary, allowing the rest of the page to still be statically cached. Previously, this was not possible. The whole page was either static or dynamic.

While the dropdown menu is loading inside the <Suspense>, we can render a placeholder:

export async function Navbar() {
  return (
    <nav className="...">
      
      [...]
      
      {/* This allows the rest of the page to be statically cached. */}
      <Suspense fallback={<UserDropdownLoader />}>
        <UserNav />
      </Suspense>
    </nav>
  );
}

async function UserNav() {
  // Fetch the dynamic data (user session) inside the Suspense
  const session = await getServerSession();
  const user = session?.user;

  return <UserDropdown user={user ?? null} />;
}

That's all there is to PPR! You wrap dynamic parts of your page into Suspense so that the remaining page can still be rendered statically.

At least, that's how I understand it 😅

Next.js 16 Course

As mentioned, I'm working on an updated Next.js 16 course that covers all the new features in Next.js, like PPR and the new "use cache" directive.

It will be the ultimate resource to become a Next.js expert in 2025 and 2026. It will be on my website once it's ready!

Happy coding!

Florian

Get my free email newsletter

I send my best web dev tips to my email subscribers.
Sign up to stay ahead of the curve.

Join for free