xiaohongshu
xiaohongshu
data-fetching
Best practices and conventions for server-side data fetching, caching, and rendering in Next.js 16+ applications.
Full skill instructions
This skill covers server-side data fetching and caching patterns using Next.js 16+ Cache Components approach with Partial Prerendering (PPR). It combines fine-grained caching control with server-side data fetching for optimal performance.
lib/actions/use cache directive in pages/layouts, not in action filesSuspense boundaries to separate static and dynamic contentcacheLife() with appropriate profileBefore implementing:
lib/actions/ or create new ones if neededFollow this pattern in pages or layouts:
import { cacheLife } from 'next/cache'
import { getModels } from '@/lib/actions/models'
export default async function ModelsPage() {
'use cache'
cacheLife('hours')
const models = await getModels()
return <div>{/* render models */}</div>
}
For runtime-dependent data (cookies, headers, searchParams):
import { Suspense } from 'react'
export default function Page() {
return (
<>
<h1>Static Content</h1>
<Suspense fallback={<Skeleton />}>
<DynamicUserContent />
</Suspense>
</>
)
}
async function DynamicUserContent() {
const session = await getSession() // uses cookies()
return <div>{session.user.name}</div>
}
Use built-in lifetime profiles with cacheLife():
| Profile | Use Case | Duration |
|---|---|---|
'seconds' | Highly volatile data | ~30 seconds |
'minutes' | Frequently updated content | ~5 minutes |
'hours' | Semi-static content | ~1 hour |
'days' | Mostly static content | ~1 day |
'weeks' | Rarely changing content | ~1 week |
'max' | Static content | Maximum duration |
Default Choice: Use 'hours' for most content unless you have specific requirements.
cacheTag for Manual InvalidationTag cached data that needs to be invalidated on specific events:
import { cacheLife, cacheTag } from 'next/cache'
import { getModelById } from '@/lib/actions/models'
export default async function ModelPage({ params }: { params: { id: string } }) {
'use cache'
cacheLife('hours')
cacheTag('models', `model-${params.id}`)
const model = await getModelById(params.id)
return <div>{/* render model */}</div>
}
updateTagUse in server actions for immediate cache expiration (read-your-own-writes):
'use server'
import { updateTag } from 'next/cache'
export async function updateModel(id: string, data: ModelData) {
// Update database via action
await updateModelAction(id, data)
// Immediately expire cache so user sees fresh data
updateTag(`model-${id}`, 'models')
}
revalidateTag for Background RefreshFor stale-while-revalidate pattern:
'use server'
import { revalidateTag } from 'next/cache'
export async function createModel(data: ModelData) {
await createModelAction(data)
// Stale-while-revalidate: serve stale, refresh in background
revalidateTag('models', 'max')
}
use cache directive in pages/layouts that consume actions, never in action files themselvescookies(), headers(), or searchParams in cached functionsupdateTag for user mutations - When users need to see their changes immediatelyrevalidateTag for background updates - When serving slightly stale data is acceptable'models' and 'model-123') for flexible invalidationimport { cacheLife, cacheTag } from 'next/cache'
import { getModels } from '@/lib/actions/models'
export default async function ModelsPage() {
'use cache'
cacheLife('hours')
cacheTag('models')
const models = await getModels()
return <div>{/* render list */}</div>
}
import { cacheLife, cacheTag } from 'next/cache'
import { getModelById } from '@/lib/actions/models'
export default async function ModelPage({ params }: { params: { id: string } }) {
'use cache'
cacheLife('hours')
cacheTag('models', `model-${params.id}`)
const model = await getModelById(params.id)
return <div>{/* render detail */}</div>
}
import { Suspense } from 'react'
import { cacheLife } from 'next/cache'
export default function Page() {
return (
<>
<StaticContent />
<Suspense fallback={<LoadingSkeleton />}>
<DynamicContent />
</Suspense>
</>
)
}
async function StaticContent() {
'use cache'
cacheLife('hours')
const data = await getStaticData()
return <div>{/* render */}</div>
}
async function DynamicContent() {
const session = await getSession() // uses cookies
const userData = await getUserData(session.userId)
return <div>{/* render */}</div>
}
'use server'
import { updateTag } from 'next/cache'
import { updateModelAction } from '@/lib/actions/models'
export async function updateModel(id: string, data: FormData) {
const result = await updateModelAction(id, data)
if (result.status === 'success') {
// Immediately expire cache for this specific model and all models
updateTag(`model-${id}`, 'models')
}
return result
}
cookies(), headers(), searchParams should not be in cached functionsuse cache to server action files; cache at the consumption pointEnable Cache Components in next.config.ts:
const nextConfig = {
cacheComponents: true,
}
export default nextConfig
cacheComponents: true is set in next.config.tsuse cache is at the top of the function bodyupdateTag instead of revalidateTag for immediate updatesSuspense boundaries to improve streamingxiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience