Partial Prerendering with Suspense
Combine static shells with streamed dynamic content using React Suspense for instant page loads.
import { Suspense } from 'react';
// Static shell — prerendered at build time
export default function ProductPage({ params }: { params: { id: string } }) {
return (
<div className="max-w-4xl mx-auto p-8">
<h1 className="text-3xl font-bold">Product Details</h1>
{/* Dynamic — streamed on request */}
<Suspense fallback={<PriceSkeleton />}>
<DynamicPrice productId={params.id} />
</Suspense>
<Suspense fallback={<ReviewsSkeleton />}>
<DynamicReviews productId={params.id} />
</Suspense>
</div>
);
}
async function DynamicPrice({ productId }: { productId: string }) {
const price = await fetchPrice(productId); // dynamic
return <p className="text-2xl">${price.amount}</p>;
}
function PriceSkeleton() {
return <div className="h-8 w-24 bg-gray-200 rounded animate-pulse" />;
}
function ReviewsSkeleton() {
return <div className="h-32 bg-gray-200 rounded animate-pulse" />;
}
async function DynamicReviews({ productId }: { productId: string }) {
return <p>Reviews for {productId}</p>;
}
async function fetchPrice(_id: string) {
return { amount: 29.99 };
}Use Cases
- E-commerce product pages
- Dashboard layouts
- Personalized content
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
Generator Pipeline for Data Processing
Chain generators to build memory-efficient data processing pipelines for large files and streams.
Streaming API Response
Stream long-running API responses using ReadableStream and TransformStream for real-time data delivery.
Next.js Image Optimization Patterns
Use next/image with responsive sizes, blur placeholders, and priority loading for optimal Core Web Vitals.
Redis Cache Get/Set Helper
Type-safe Redis cache wrapper with automatic JSON serialization, TTL support, and cache-aside pattern.