Partial Pre-Rendering in Next.js 15

PPR, or Partial-Pre Rendering, is a new rendering strategy introduced in Next.js. It allows for combining static and dynamic components on the same page without sacrificing performance.

Your Next Store, a modern Shopify competitor, leverages PPR extensively to deliver the fastest experience possible. In this article, we will explore the benefits of PPR, its implementation in Next.js 15, and how it can be leveraged in applications like Your Next Store.

PPR vs Other Rendering Methods in E‑commerce

Partial Pre-Rendering differs from other rendering strategies you might've heard of: Static Site Generation (SSG), Server-Side Rendering (SSR), and Incremental Static Regeneration (ISR).

  • SSG generates the entire HTML at build time, making it ideal for static content. However, it struggles with dynamic components or frequent content changes.
  • SSR, on the other hand, renders pages on each request, providing always up-to-date content at the cost of server load and latency.
  • ISR is an evolution of SSG, where static pages are regenerated at predefined time intervals or on demand. However, it still suffers from some of the same drawbacks as SSG: stale content. Pages are not updated immediately when the data changes.

PPR introduces a new level of flexibility and performance to Next.js applications. With PPR, pages can be both pre-rendered and dynamic at the same time – no need to choose. It allows for both amazing speed and up-to-date content.

In the example below, we can see the homepage of the Your Next Store storefront. Most of the page is highlighted as “Static,” meaning that the components don't need any dynamic data and can be statically pre-rendered. Some of the components, such as the cart, always require the latest data and hence are dynamic. Thanks to PPR, we can have both on the same page without losing performance.

Understanding Partial Pre-Rendering (PPR)

The short description of PPR is that, during the build, Next.js statically pre-renders as much as possible and leaves out specific components. How does it know which components should be pre-rendered?

Whenever Next.js comes across dynamic code (e.g., reading cookies or fetching without cache), it'll mark that component as dynamic. It'll also mark the whole component tree above it as dynamic, up to the nearest Suspense boundary. To prevent that and fully utilize PPR, we need to wrap certain dynamic components in a Suspense component. Optionally, we can use the fallback prop to provide content that should be displayed while the dynamic component is being rendered.

Once it's done, Suspense fallbacks will be included in the pre-rendered HTML along with static components. When users visit your app, they'll instantly see all pre-rendered data and the fallbacks.

Now, dynamic components start streaming from the server to the browser. The components are streamed in parallel, so we avoid waterfalls and see content quicker. Moreover, to further optimize speed, the Next.js server starts streaming them even before the client JavaScript bundle is loaded in the browser. Once the data is received, fallbacks are replaced with real content.

A Step-by-Step Guide to Implementing PPR

Let's take a real-world example from the e‑commerce area. We have a single product page with a title, picture, price, and short description. Additionally, at the bottom of the page, there's a list of related products generated by AI.

Product details can be completely static. They change rather infrequently, and we can revalidate them on demand. However, the “Related Products” section in our case is dynamic. It changes depending on the current product as well as other products in the product catalog. The code below was simplified for brevity:

export function ProductDetails() {
return (
<>
<main>
<p>Your Next Store</p>
<h1>Sunbeam Tote</h1>
<p>$10.99</p>
<Image src="…" alt="" /* … */ />

<p>Brighten your day with this cheerful yellow bag. Its vibrant color and ample storage space make it an excellent choice for shopping or day trips. Lightweight and durable, it's designed for comfort and convenience.</p>

<button /* … */>Add to cart</button>
</main>

<aside>
<RelatedProducts />
</aside>
</>
);
}

For the sake of this example, let’s say that fetching related products takes 4 seconds. Obviously, 4 seconds is extremely high, but it’ll help us see the problem better.

As we can see, the RelatedProducts component prevents the whole app from loading! The page is completely dynamic, even though the rest of the product details are not. We can fix that with just two lines of code:

export function ProductDetails() {
return (
<>
<main>
<p>Your Next Store</p>
<h1>Sunbeam Tote</h1>
<p>$10.99</p>
<Image src="…" alt="" /* … */ />

<p>Brighten your day with this cheerful yellow bag. Its vibrant color and ample storage space make it an excellent choice for shopping or day trips. Lightweight and durable, it's designed for comfort and convenience.</p>

<button /* … */>Add to cart</button>
</main>

<aside>
<Suspense>
<RelatedProducts />
</Suspense>
</aside>
</>
);
}

Thanks to adding the suspense boundary – wrapping RelatedProducts in a Suspense component – Next.js is now able to determine that part of the page is static and immediately return it as HTML. Related Products, on the other hand, are rendered afterward thanks to HTTP streaming.

This is the perfect solution, especially in the e‑commerce context, where parts of the page should be delivered to the users as soon as possible, while some pieces that are slightly less relevant, can be rendered a bit later. That’s exactly what we’re doing in Your Next Store for listing related products and collections, cart, search, 3D models preview, and multiple places in our cloud dashboard.

Conclusion

Partial Pre-Rendering (PPR) in Next.js 15 makes it easier than ever to build fast, dynamic web experiences. It gives you the best of both worlds: quick load times for static content and real-time updates for dynamic features. For developers and users alike, it’s a win-win.

Your Next Store is built with PPR at its core, delivering a fast, smooth experience that feels effortless. Whether it’s blazing-fast product pages or real-time updates in the cart, PPR helps us set a new bar for what e‑commerce can be.

Want to see it in action? Check out Your Next Store and see what PPR can do.