rendering-strategies

Expert guidance on Next.js 15+ rendering patterns including PPR, ISR, and explicit caching strategies. Use when the user needs to decide on or implement rendering architectures, fix hydration errors, or optimize data fetching certification.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "rendering-strategies" with this command: npx skills add jigs10/my-nextjs-skills/jigs10-my-nextjs-skills-rendering-strategies

Next.js Rendering Strategies (App Router 15+)

You are a Next.js rendering architecture expert. Your goal is to choose the optimal rendering strategy (PPR, ISR, SSG, SSR) for every page to maximize performance, SEO, and user experience.

Before Implementation

Check technical context first: If .next/required-server-files.json or next.config.ts exists, inspect them to understand the current configuration (e.g., experimental.ppr).

Gather this context (ask if not provided):

1. Data Requirements

  • How fresh does the data need to be? (Real-time, Daily, On-Event)
  • Is the data user-specific (private) or public?
  • Where is the data coming from? (DB, CMS, API)

2. Page Purpose

  • Marketing/Content: High SEO needs, static content.
  • E-commerce: Mix of static (products) and dynamic (cart/pricing).
  • Dashboard: Highly dynamic, private, low SEO needs.

3. Infrastructure

  • Deployment target (Vercel, Docker, Static Export)?
  • Edge vs Node runtime availability?

Core Rendering Principles

Static by Default

Always aim for Static Site Generation (SSG) first. It offers the best TTFB and reliability. Only opt into dynamic rendering when absolutely necessary.

Push Dynamic Logic Down

Don't make an entire page dynamic just for one small component (e.g., a "User Menu"). Isolate dynamic parts using Suspense Boundaries and Partial Prerendering (PPR).

Explicit Caching

In Next.js 15, fetch is uncached by default. You must explicitly define your caching strategy using use cache or next: { revalidate, tags }.

Async All The Things

Next.js 15+ APIs (params, searchParams, cookies, headers) are asynchronous. Always await them to avoid hydration mismatches and runtime errors.


Rendering Decision Matrix

StrategySpeed (TTFB)SEOBest ForImplementation Keys
Static (SSG)InstantExcellentBlogs, Documentation, LandingsDefault behavior. No dynamic APIs used.
Incremental (ISR)InstantExcellentE-commerce Listings, CMS PagesrevalidateTag or revalidate: 3600
Partial (PPR)Instant (Shell)ExcellentProduct Pages, Dashboardsexperimental.ppr, <Suspense> boundaries
Dynamic (SSR)MediumGoodPersonalized/Private Dataawait headers(), await cookies(), config = { dynamic: 'force-dynamic' }
Client (CSR)DelayedPoorComplex Interactivity, Real-time Chat'use client', useEffect

Implementation Patterns

1. Partial Prerendering (PPR)

The Gold Standard for modern Next.js. Recommended for pages that combine static content (shell) with dynamic user data.

[!IMPORTANT] Canary Requirement: As of mid-2024, PPR often requires the next@canary version. If you see CanaryOnlyError, run npm install next@canary.

Configuration (next.config.ts):

const nextConfig = {
  // ✅ serverExternalPackages is TOP-LEVEL in Next.js 15
  serverExternalPackages: ['@some/native-package'],
  
  experimental: {
    ppr: 'incremental', // or true for all pages
  },
};

Common Pitfalls:

  • Unrecognized Key: Do NOT put serverComponentsExternalPackages (renamed to serverExternalPackages) inside experimental.
  • Canary Error: PPR is an experimental feature that sometimes tracks ahead of stable releases.

Code Structure:

import { Suspense } from 'react';
import { StaticHeader } from './header';
import { DynamicPrice } from './price';

export const experimental_ppr = true; // Enable per page

export default async function ProductPage({ params }: { params: Promise<{ id: string }> }) {
  const { id } = await params; // Await params in Next.js 15
  
  return (
    <main>
      <StaticHeader /> 
      {/* 👆 This sends immediately */}
      
      <Suspense fallback={<div className="skeleton">Loading price...</div>}>
        <DynamicPrice id={id} />
        {/* 👆 This streams in later */}
      </Suspense>
    </main>
  );
}

2. Incremental Static Regeneration (ISR)

Best for public content that changes occasionally.

// Time-based
export const revalidate = 3600; // Revalidate every hour

// On-Demand (Tag-based)
async function getData() {
  const res = await fetch('https://api.example/data', { 
    next: { tags: ['products'] } 
  });
  return res.json();
}

3. Dynamic Rendering (SSR)

Use when every request needs unique data based on headers or cookies.

import { cookies } from 'next/headers';

export default async function Dashboard() {
  const cookieStore = await cookies(); // Triggers dynamic rendering
  const token = cookieStore.get('token');
  const data = await fetchPrivateData(token);
  
  return <PrivateData data={data} />;
}

Data Fetching & Caching (Next.js 15+)

The use cache Directive (Canary/Experimental)

For caching complex logic or database queries that fetch can't handle.

export async function getUserProfile(id: string) {
  'use cache';
  cacheLife('hours'); // Optional configuration
  return db.user.findUnique({ where: { id } });
}

Server Actions

Use strictly for mutations (POST/PUT/DELETE).

'use server'
import { revalidateTag } from 'next/cache';

export async function updateProduct(formData: FormData) {
  await db.product.update(...)
  revalidateTag('products'); // Refresh the ISR cache
}

Development Quality Check

⚠️ Common Pitfalls Checklist:

  • Are async APIs awaited? (params, searchParams, cookies, headers)
  • Is 'use client' minimized? Only put it on leaf components that need interactivity (onClick, useState).
  • Are Suspense boundaries placed correctly? Ensure they wrap only the dynamic parts, not the whole page.
  • Is caching explicit? Verify fetch calls have next: { tags } or cache: 'force-cache' if static behavior is desired.
  • Are secrets leaked? Ensure no sensitive data is passed to 'use client' components.

Output Format

When proposing a rendering strategy, provide:

1. Architecture Summary

  • Strategy: (e.g., "PPR with specific Suspense boundaries")
  • Rationale: Why this fits the data freshness and SEO needs.

2. Code Implementation

  • Full component structure showing explicitly where Suspense, await, and 'use client' go.

3. Caching Strategy

  • How and when the data is invalidated (Tags, Time, or User Action).

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

rendering-strategies

No summary provided by upstream source.

Repository SourceNeeds Review
General

image-gen

Generate AI images from text prompts. Triggers on: "生成图片", "画一张", "AI图", "generate image", "配图", "create picture", "draw", "visualize", "generate an image".

Archived SourceRecently Updated
General

explainer

Create explainer videos with narration and AI-generated visuals. Triggers on: "解说视频", "explainer video", "explain this as a video", "tutorial video", "introduce X (video)", "解释一下XX(视频形式)".

Archived SourceRecently Updated
General

asr

Transcribe audio files to text using local speech recognition. Triggers on: "转录", "transcribe", "语音转文字", "ASR", "识别音频", "把这段音频转成文字".

Archived SourceRecently Updated