Skip to content

Gentleman-Programming/nextjs-15-revalidation-demo

Repository files navigation

Next.js 15 Revalidation Demo

English | Español


English

🎯 Purpose

This project demonstrates the importance of revalidatePath() in Next.js 15 Server Actions when dealing with external data changes.

The Problem: When data changes externally (via webhooks, cron jobs, or other systems), calling a GET Server Action without revalidatePath() won't refresh the UI because the cache isn't invalidated.

The Solution: Using revalidatePath() in your GET Server Action invalidates the cache and allows Next.js to fetch fresh data.

🚀 Quick Start

# Install dependencies
npm install

# Run in development mode
npm run dev

# Build for production
npm run build
npm start

Open http://localhost:3000 in your browser.

📖 How It Works

Problem Demo (/problem)

  1. Click "🌍 Insert External" - simulates an external system adding data to the database
  2. Click "🔄 GET Server Action" - calls a GET Server Action WITHOUT revalidatePath()
  3. ❌ The new product doesn't appear because the cache wasn't invalidated

Why? Without revalidatePath(), Next.js uses cached data and doesn't know it needs to refetch.

Solution Demo (/solution)

  1. Click "🌍 Insert External" - simulates an external system adding data to the database
  2. Click "✅ GET + Revalidate" - calls a GET Server Action WITH revalidatePath()
  3. ✅ The new product appears immediately because the cache was invalidated

Why? revalidatePath() tells Next.js to invalidate the cache and fetch fresh data on the next render.

🔑 Key Concepts

Server Actions

Functions that run 100% on the server, marked with 'use server':

'use server';

export async function refreshProducts(filters: FilterOptions) {
  const products = await getFilteredProducts(filters);

  // ✅ This is the key - invalidate the cache
  revalidatePath('/solution');

  return { success: true, products };
}

revalidatePath()

Invalidates the Next.js cache for a specific path:

import { revalidatePath } from 'next/cache';

// Invalidate cache for a specific route
revalidatePath('/products');

// Invalidate cache for all routes
revalidatePath('/', 'layout');

When to Use revalidatePath

Operation Use revalidatePath? Why?
GET (reading data after external change) ✅ Yes Cache needs to be invalidated
POST (creating data) ✅ Yes New data needs to be reflected
PUT (updating data) ✅ Yes Updated data needs to be shown
DELETE (removing data) ✅ Yes Removed data should disappear
Filter changes ❌ No URL change triggers refetch automatically
Pagination ❌ No URL change triggers refetch automatically

📁 Project Structure

nextjs-revalidation-demo/
├── app/
│   ├── problem/          # Demo WITHOUT revalidatePath
│   │   ├── actions.ts           # Server Actions (no revalidate)
│   │   ├── page.tsx             # Server Component
│   │   └── filter-controls.tsx  # Client Component
│   │
│   ├── solution/         # Demo WITH revalidatePath
│   │   ├── actions.ts           # Server Actions (with revalidate)
│   │   ├── page.tsx             # Server Component
│   │   └── filter-controls.tsx  # Client Component
│   │
│   └── api/
│       └── external-insert/     # API Route (simulates external system)
│
├── lib/
│   ├── db/
│   │   └── mock-db.ts    # In-memory database
│   └── dal/
│       └── products.ts   # Data Access Layer
│
└── components/
    ├── product-table.tsx
    └── ui/               # UI components

🛠️ Tech Stack

  • Next.js 15.1.8 - React framework with App Router
  • React 19 - UI library
  • TypeScript - Type safety
  • Tailwind CSS - Styling
  • Turbopack - Ultra-fast bundler

📚 Learn More

📝 License

MIT


Español

🎯 Propósito

Este proyecto demuestra la importancia de revalidatePath() en Next.js 15 Server Actions cuando se trabaja con cambios de datos externos.

El Problema: Cuando los datos cambian externamente (vía webhooks, cron jobs, u otros sistemas), llamar a un GET Server Action sin revalidatePath() no actualizará la UI porque el cache no se invalida.

La Solución: Usar revalidatePath() en tu GET Server Action invalida el cache y permite a Next.js obtener datos frescos.

🚀 Inicio Rápido

# Instalar dependencias
npm install

# Ejecutar en modo desarrollo
npm run dev

# Build para producción
npm run build
npm start

Abre http://localhost:3000 en tu navegador.

📖 Cómo Funciona

Demo del Problema (/problem)

  1. Haz clic en "🌍 Insertar Externo" - simula un sistema externo agregando datos a la base de datos
  2. Haz clic en "🔄 GET Server Action" - llama a un GET Server Action SIN revalidatePath()
  3. ❌ El nuevo producto no aparece porque el cache no fue invalidado

¿Por qué? Sin revalidatePath(), Next.js usa datos cacheados y no sabe que necesita re-obtener los datos.

Demo de la Solución (/solution)

  1. Haz clic en "🌍 Insertar Externo" - simula un sistema externo agregando datos a la base de datos
  2. Haz clic en "✅ GET + Revalidate" - llama a un GET Server Action CON revalidatePath()
  3. ✅ El nuevo producto aparece inmediatamente porque el cache fue invalidado

¿Por qué? revalidatePath() le dice a Next.js que invalide el cache y obtenga datos frescos en el siguiente render.

🔑 Conceptos Clave

Server Actions

Funciones que se ejecutan 100% en el servidor, marcadas con 'use server':

'use server';

export async function refreshProducts(filters: FilterOptions) {
  const products = await getFilteredProducts(filters);

  // ✅ Esta es la clave - invalidar el cache
  revalidatePath('/solution');

  return { success: true, products };
}

revalidatePath()

Invalida el cache de Next.js para una ruta específica:

import { revalidatePath } from 'next/cache';

// Invalidar cache para una ruta específica
revalidatePath('/products');

// Invalidar cache para todas las rutas
revalidatePath('/', 'layout');

Cuándo Usar revalidatePath

Operación ¿Usar revalidatePath? ¿Por qué?
GET (leer datos después de cambio externo) ✅ Sí El cache necesita invalidarse
POST (crear datos) ✅ Sí Los nuevos datos deben reflejarse
PUT (actualizar datos) ✅ Sí Los datos actualizados deben mostrarse
DELETE (eliminar datos) ✅ Sí Los datos eliminados deben desaparecer
Cambio de filtros ❌ No El cambio de URL dispara refetch automáticamente
Paginación ❌ No El cambio de URL dispara refetch automáticamente

📁 Estructura del Proyecto

nextjs-revalidation-demo/
├── app/
│   ├── problem/          # Demo SIN revalidatePath
│   │   ├── actions.ts           # Server Actions (sin revalidate)
│   │   ├── page.tsx             # Server Component
│   │   └── filter-controls.tsx  # Client Component
│   │
│   ├── solution/         # Demo CON revalidatePath
│   │   ├── actions.ts           # Server Actions (con revalidate)
│   │   ├── page.tsx             # Server Component
│   │   └── filter-controls.tsx  # Client Component
│   │
│   └── api/
│       └── external-insert/     # API Route (simula sistema externo)
│
├── lib/
│   ├── db/
│   │   └── mock-db.ts    # Base de datos en memoria
│   └── dal/
│       └── products.ts   # Capa de Acceso a Datos
│
└── components/
    ├── product-table.tsx
    └── ui/               # Componentes UI

🛠️ Stack Tecnológico

  • Next.js 15.1.8 - Framework React con App Router
  • React 19 - Librería UI
  • TypeScript - Tipado estático
  • Tailwind CSS - Estilos
  • Turbopack - Bundler ultra-rápido

📚 Aprende Más

📝 Licencia

MIT


Made with ❤️ to help the Next.js community understand revalidation

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages