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

ll-feishu-audio

飞书语音交互技能。支持语音消息自动识别、AI 处理、语音回复全流程。需要配置 FEISHU_APP_ID 和 FEISHU_APP_SECRET 环境变量。使用 faster-whisper 进行语音识别,Edge TTS 进行语音合成,自动转换 OPUS 格式并通过飞书发送。适用于飞书平台的语音对话场景。

Archived SourceRecently Updated
General

test_skill

import json import tkinter as tk from tkinter import messagebox, simpledialog

Archived SourceRecently Updated
General

51mee-resume-profile

简历画像。触发场景:用户要求生成候选人画像;用户想了解候选人的多维度标签和能力评估。

Archived SourceRecently Updated