slug: nextjs-15-partial-prerendering-ppr-ecommerce-guide title: Next.js 15 Partial Prerendering (PPR): The Ultimate E-commerce Guide description: >- Boost e-commerce speed and SEO with Next.js 15 Partial Prerendering (PPR). Learn how to combine static shells with dynamic fragments seamlessly for high-performance web apps. date: 2026-04-03T00:00:00.000Z readTime: 12 min category: Developer Tooling tags:
- Next.js
- React
- Performance
- E-commerce
- '2026' author: UnterGletscher Team lastUpdated: 2026-04-03T00:00:00.000Z
Next.js 15 Partial Prerendering (PPR): The Ultimate E-commerce Guide
In the competitive world of e-commerce, every millisecond counts. Amazon famously found that every 100ms of latency cost them 1% in sales. For years, developers have struggled with a fundamental trade-off: do you choose the speed and SEO benefits of Static Site Generation (SSG), or the personalization and real-time data of Server-Side Rendering (SSR)?
Next.js 15 introduces a groundbreaking solution to this dilemma: Partial Prerendering (PPR). This feature allows you to combine static and dynamic rendering on the same route, delivering the best of both worlds without the architectural complexity of traditional hybrid approaches.
In this guide, we will dive deep into how PPR works, why it is a game-changer for e-commerce, and how you can implement it in your Next.js 15 projects today.
What is Partial Prerendering (PPR)?
Partial Prerendering is an optimization that allows a route to be partially prerendered at build time (or during revalidation), while leaving "holes" for dynamic content that are filled at request time.
Think of an e-commerce product page. Most of the content—the product name, description, and images—is static and doesn't change for every user. However, the stock status, pricing (if personalized), and the shopping cart contents are highly dynamic.
Traditionally, you would have to:
- SSR the entire page: Slowing down Time to First Byte (TTFB) for all users.
- SSG the page and fetch dynamic data on the client: Leading to layout shifts (CLS) and a "loading state" experience that can hurt conversion.
PPR changes this by sending a static "shell" immediately, and then streaming the dynamic fragments as they become ready.
How PPR Works: The Static Shell and Dynamic Holes
The magic of PPR lies in its integration with React Suspense. When you enable PPR, Next.js analyzes your component tree.
1. The Static Shell
Any part of your page that does not use dynamic functions (like cookies(), headers(), or uncached data fetches) is prerendered into a static HTML shell. This shell includes your navigation, layout, and the static parts of your page content. When a user requests the page, this shell is served instantly from the edge.
2. Dynamic Holes
Parts of your page wrapped in <Suspense /> that contain dynamic logic are treated as "holes." While the static shell is being sent to the browser, the server continues to execute the dynamic components. Once the dynamic data is fetched and the component is rendered, the resulting HTML is streamed to the browser and "popped" into the correct location.
The Result
The user sees the page layout and primary content almost instantly. The dynamic parts (like "Items in Cart" or "Recommended for You") appear a moment later without triggering a full-page layout shift.
Why PPR is a Game-Changer for E-commerce
1. Superior Core Web Vitals
By serving a static shell from the CDN edge, you drastically improve your Time to First Byte (TTFB) and First Contentful Paint (FCP). Because the dynamic content is streamed into reserved Suspense boundaries, you also minimize Cumulative Layout Shift (CLS), provided you use appropriate loading skeletons.
2. Enhanced SEO
Search engines love fast pages. PPR ensures that the most important SEO content—titles, descriptions, and primary product data—is available immediately in the initial HTML response. Unlike pure client-side fetching, where bots might see an empty shell, PPR provides a meaningful document from the start.
3. Seamless Personalization
Personalization is key to modern e-commerce. Whether it's showing a "Welcome back, [Name]" message or displaying regional pricing, PPR allows you to keep the bulk of the page static while personalizing specific fragments. This avoids the "flash of unauthenticated content" often seen in client-side apps.
4. Reduced Server Load
Because the majority of the page is prerendered and cached at the edge, the server only needs to execute the logic for the dynamic "holes." This significantly reduces the compute resources required compared to traditional SSR, where the entire page must be rendered on every request.
Implementing PPR in Next.js 15
As of Next.js 15, PPR is still an experimental feature, but it is highly stable and recommended for testing in performance-critical applications like e-commerce stores.
Step 1: Enable the Experimental Flag
First, you must opt-in to PPR in your next.config.ts (or .js) file:
// next.config.ts
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
experimental: {
ppr: 'incremental', // Use 'incremental' to opt-in per route
},
};
export default nextConfig;
Step 2: Opt-in at the Route Level
With the incremental flag, you can choose which routes use PPR. Add the experimental_ppr constant to your layout or page file:
// app/products/[slug]/page.tsx
export const experimental_ppr = true;
export default function ProductPage({ params }) {
return (
<main>
<ProductDetails slug={params.slug} />
<Suspense fallback={<CartSkeleton />}>
<DynamicCartSummary />
</Suspense>
<Suspense fallback={<RecommendationSkeleton />}>
<RelatedProducts slug={params.slug} />
</Suspense>
</main>
);
}
Step 3: Use React Suspense Strategically
The key to successful PPR is where you place your <Suspense /> boundaries.
- Wrap Dynamic Components: Any component that calls
cookies(),headers(), or performs a dynamic fetch must be wrapped in Suspense. - Provide Skeletons: Use loading skeletons that match the final dimensions of the dynamic content to prevent layout shifts.
The "dynamicIO" and "use cache" Primitives
Next.js 15 also introduces the dynamicIO flag and the use cache directive, which complement PPR. In the new model, Next.js moves away from "caching by default" to a more explicit "opt-in" model.
dynamicIO: When enabled, it ensures that any data fetching or dynamic access outside of ause cacheboundary or a Suspense-wrapped dynamic component will trigger an error during build time if not handled. This makes your performance profile much more predictable.use cache: This is a new directive (similar to"use server") that allows you to cache the output of a function or component. Combined with PPR, you can cache specific expensive computations or API calls while keeping the rest of the route dynamic.
Best Practices for E-commerce PPR
1. Optimize Your Skeletons
Since the static shell is delivered instantly, users will see your loading skeletons. Make them look as close to the final content as possible. For product cards, include the aspect ratio of the image and the approximate height of the text blocks.
2. Keep the "Fold" Static
Ensure that everything "above the fold" (visible without scrolling) is mostly static. If the primary product image or price is dynamic, it will delay the Largest Contentful Paint (LCP). Try to keep essential SEO and conversion elements in the static shell.
3. Monitor Your Dynamic Holes
Every dynamic hole in your page adds a small amount of overhead. While PPR is efficient, having dozens of tiny dynamic holes can lead to "pop-in" fatigue for the user. Group related dynamic elements into a single Suspense boundary where appropriate.
4. Use "use cache" for Global Data
If you have data that is dynamic but shared across many users (like global inventory levels that update every few minutes), use the use cache directive with a revalidation period (ISR) to avoid hitting your database on every single request.
Frequently Asked Questions (FAQ)
Q1: Is PPR ready for production?
Next.js 15 classifies PPR as experimental. While many large-scale sites are already testing it, you should use it with caution. The "incremental" opt-in allows you to test it on low-traffic pages before rolling it out to your primary product pages.
Q2: Does PPR replace Incremental Static Regeneration (ISR)?
No, they are complementary. ISR determines when a page is updated, while PPR determines how the page is rendered and delivered. You can use ISR to update the static shell of a PPR page every hour, while the dynamic holes continue to fetch real-time data on every request.
Q3: How does PPR affect my hosting costs?
PPR can actually lower costs by reducing the compute needed for each request. Since the shell is cached at the edge, you save on server execution time. However, ensure your streaming-capable hosting provider (like Vercel or AWS with Lambda streaming) is configured correctly.
Q4: Can I use PPR with the Pages Router?
No, PPR is an exclusive feature of the Next.js App Router, as it relies on the deep integration between the App Router's file-system-based metadata and React's Server Components and Suspense.
Q5: Will PPR work if the user has a slow connection?
Yes, PPR is actually better for slow connections. The browser receives the static shell immediately, which contains the CSS and basic structure. This allows the browser to start parsing and rendering the page while waiting for the dynamic chunks to arrive over the stream.
Conclusion
Next.js 15 Partial Prerendering (PPR) is more than just a performance tweak; it is a paradigm shift in how we build dynamic web applications. By removing the wall between static and dynamic rendering, PPR allows e-commerce developers to build stores that are both blindingly fast and deeply personal.
As we move through 2026, we expect PPR to become the standard for high-performance commerce. By implementing it now, you can gain a significant competitive advantage in SEO, user experience, and conversion rates.
For more guides on high-performance web development, check out our Developer Tooling section.