# Nextjs Caching

> >

- **Type:** Skill
- **Install:** `agentstack add skill-t-code4change-nextjs-claude-skills-nextjs-caching`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [t-code4change](https://agentstack.voostack.com/s/t-code4change)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [t-code4change](https://github.com/t-code4change)
- **Source:** https://github.com/t-code4change/nextjs-claude-skills/tree/main/nextjs-caching

## Install

```sh
agentstack add skill-t-code4change-nextjs-claude-skills-nextjs-caching
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Next.js Caching (Cache Components)

> Requires: `cacheComponents: true` in `next.config.ts` (Next.js 16).

---

## Project Detection

```bash
grep -r "cacheComponents" next.config.* 2>/dev/null
```

---

## Enable

```typescript
// next.config.ts
const nextConfig: NextConfig = { cacheComponents: true };
export default nextConfig;
```

---

## Decision Steps

1. Does component fetch data? No → skip. Yes → continue.
2. Depends on `cookies()`/`headers()`/`searchParams`? No → step 3. Yes → step 4.
3. Same data for all users? Yes → `'use cache'` + `cacheTag()` + `cacheLife()`. No → ``.
4. Can extract runtime data as args? Yes → pass outside cache. No → `'use cache: private'` (last resort).

---

## Core APIs

### `'use cache'` Directive

```tsx
async function BlogPosts() {
  'use cache';        // MUST be first statement; function MUST be async
  cacheTag('posts');
  cacheLife('hours');
  return await db.posts.findMany();
}
```

### `cacheLife()` Profiles

```tsx
cacheLife('seconds');  // stale:30s  | revalidate:1s   | expire:1m
cacheLife('minutes');  // stale:5m   | revalidate:1m   | expire:1h
cacheLife('hours');    // stale:5m   | revalidate:1h   | expire:1d
cacheLife('days');     // stale:5m   | revalidate:1d   | expire:1w
cacheLife('weeks');    // stale:5m   | revalidate:1w   | expire:30d
cacheLife('max');      // stale:5m   | revalidate:30d  | expire:1y
// Custom:
cacheLife({ stale: 60, revalidate: 3600, expire: 86400 });
```

**By content type:** news → `seconds`, blog/docs → `hours`, marketing → `days`, legal → `max`

### `cacheTag()` + Invalidation

```tsx
// Tag
async function ProductList({ category }: { category: string }) {
  'use cache';
  cacheTag('products', `category-${category}`);
  cacheLife('hours');
  return await db.products.findMany({ where: { category } });
}

// Invalidate — Server Action (immediate, read-your-own-writes)
'use server';
export async function createProduct(formData: FormData): Promise {
  await db.products.create({ data: parseFormData(formData) });
  updateTag('products');
}

// Invalidate — Route Handler / webhook (stale-while-revalidate)
export async function POST(request: Request) {
  const { tag } = await request.json();
  revalidateTag(tag, 'max');  // two-arg form — single arg is DEPRECATED
  return Response.json({ revalidated: true });
}
```

---

## Server Actions vs Data Fetching (CRITICAL)

```tsx
// ❌ WRONG: Server Action for data fetch
'use server';
export async function getProducts() { return await db.products.findMany(); }

// ✅ CORRECT: cached data function
export async function getProducts() {
  'use cache';
  cacheTag('products');
  cacheLife('hours');
  return await db.products.findMany();
}

// ✅ CORRECT: Server Action for mutation only
'use server';
export async function createProduct(formData: FormData): Promise {
  await db.products.create({ data: formData });
  updateTag('products');
}
```

---

## PPR Pattern

```tsx
export default async function ProductPage({ params }) {
  const { id } = await params;
  return (
    <>
                          {/* static */}
           {/* 'use cache' — in static shell */}
      }>
                                {/* dynamic — streams after load */}
      
    
  );
}

async function CachedProductDetails({ id }: { id: string }) {
  'use cache';
  cacheTag(`product-${id}`);
  cacheLife('hours');
  const product = await db.products.findUnique({ where: { id } });
  return ;
}
```

---

## Runtime Data Pattern (cookies inside cache)

```tsx
// ❌ WRONG: cookies() inside 'use cache'
async function UserData() {
  'use cache';
  const cookieStore = await cookies();  // ERROR
}

// ✅ CORRECT: extract outside, pass as arg
async function UserDataWrapper() {
  const cookieStore = await cookies();
  const userId = cookieStore.get('userId')?.value;
  return ;
}

async function CachedUserData({ userId }: { userId: string }) {
  'use cache';
  cacheTag(`user-${userId}`);
  cacheLife('minutes');
  return await getUser(userId);
}
```

---

## Review Checklist

- [ ] `cacheComponents: true` in `next.config.ts`
- [ ] All `'use cache'` functions are `async`
- [ ] `'use cache'` is first statement
- [ ] `cacheTag()` present (enables targeted invalidation)
- [ ] `cacheLife()` present (don't rely on defaults)
- [ ] `cookies()`/`headers()` NOT inside `'use cache'` scope
- [ ] Server Actions call `updateTag()` after mutations
- [ ] Dynamic components wrapped in ``
- [ ] `revalidateTag(tag, profile)` — two-arg form (not deprecated single-arg)
- [ ] Server Actions return `void`, never used for data fetching

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [t-code4change](https://github.com/t-code4change)
- **Source:** [t-code4change/nextjs-claude-skills](https://github.com/t-code4change/nextjs-claude-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-t-code4change-nextjs-claude-skills-nextjs-caching
- Seller: https://agentstack.voostack.com/s/t-code4change
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
