Augustine Cobbold
← Back to blog
Partial Prerendering (PPR) & Server Actions in Next.js: Lessons Learned in Production

Partial Prerendering (PPR) & Server Actions in Next.js: Lessons Learned in Production

Next.js
React 19
Partial Prerendering
Server Actions
Full-Stack Web
Web Performance

10/08/2026 - 7 min read

By Augustine Cobbold

The Static vs Dynamic Dilemma

For years, web developers had to choose between two architectural extremes: static generation (SSG) for blistering CDN delivery, or dynamic server rendering (SSR) for personalized, real-time user data. Static sites lacked real-time freshness; dynamic sites suffered from slower Time-to-First-Byte (TTFB).

Partial Prerendering (PPR) solves this by combining both in a single HTTP request. The static layout shell (navbars, headers, hero marketing) is served instantly from edge cache, while dynamic components stream in parallel over the open connection wrapped in React Suspense boundaries.

Hardening Server Actions for Production

Server Actions simplify form handling and RPC mutations, but exposing backend logic directly to client components requires rigorous validation and authorization. Never trust client payloads:

'use server';

import { z } from 'zod';
import { revalidateTag } from 'next/cache';
import { auth } from '@/lib/auth';

const FeedbackSchema = z.object({
  message: z.string().min(5).max(1000),
  rating: z.number().int().min(1).max(5),
});

export async function submitUserFeedback(formData: FormData) {
  const session = await auth();
  if (!session) {
    return { error: 'Unauthorized' };
  }

  const parse = FeedbackSchema.safeParse({
    message: formData.get('message'),
    rating: Number(formData.get('rating')),
  });

  if (!parse.success) {
    return { error: 'Invalid submission data', issues: parse.error.issues };
  }

  await db.feedback.create({
    data: { userId: session.user.id, ...parse.data }
  });

  revalidateTag('feedback', 'max');
  return { success: true };
}

Summary

Partial Prerendering and Server Actions transform Next.js into a powerhouse for high-conversion web products. By separating static layout chrome from dynamic streaming holes, teams deliver both enterprise security and instant sub-second page transitions.