On-Demand Revalidation
v5.1.0+Purge and regenerate the static page cache of your application on-demand in production when data changes, without rebuilding the whole site.
Overview
Dinou provides Incremental Static Regeneration (ISR) by default. However, when mutative actions occur (e.g. database updates), you want page cache purges to be instant. The On-Demand Revalidation API enables purging specific routes or groups of routes tagged with custom cache keys.
These APIs are exported from the server-only endpoint "dinou/server", keeping browser bundles completely clean of Node.js dependencies.
revalidatePath
Cleans the static cache files for a given route and immediately triggers a background recompilation to promote the new static output.
Absolute Paths
Pass an absolute pathname to revalidate that specific route directly:
// src/products/actions.ts
"use server";
import { revalidatePath } from "dinou/server";
export async function updateProduct(id, data) {
await db.updateProduct(id, data);
// Revalidate the specific product page and the main index
await revalidatePath(`/products/${id}`);
await revalidatePath("/products");
}Relative Paths
When called inside a Server Function, revalidatePath can resolve relative paths based on the browser url (extracted from the HTTP referer header):
// src/demo/isr/actions.ts
"use server";
import { revalidatePath } from "dinou/server";
export async function triggerRevalidate() {
// Revalidate the page that initiated this Server Function call (e.g., /demo/isr)
await revalidatePath("./");
// Revalidate an adjoined/adjacent route (e.g., /demo/dashboard)
await revalidatePath("../dashboard");
}revalidateTag
Revalidates all static pages associated with a specific cache tag. This allows groups of pages to be invalidated in a single call.
// src/products/actions.ts
"use server";
import { revalidateTag } from "dinou/server";
export async function addNewProduct(data) {
await db.insertProduct(data);
// Revalidate all pages tagged with 'products'
await revalidateTag("products");
}metadata.json inside dist2/ during builds and generation.Best Practices & Safety Guidelines
Strict Execution Rules
Only Call in Event Contexts: Revalidation APIs are mutative events. They should only be invoked inside Server Functions (Server Actions), Express request endpoints (like webhooks), or standalone Node.js cron/sync scripts.
Do NOT Call inside getProps or Components: Never invoke revalidatePath or revalidateTag during the rendering phase of a React Component, or inside getProps hooks. Doing so will trigger infinite compilation loops that will crash the server.
Running in Webhooks
To trigger revalidation remotely, define a standard POST route inside your Express server.js file:
// server.js
const { revalidateTag } = require("dinou/server");
app.post("/api/revalidate", express.json(), async (req, res) => {
const { tag } = req.body;
try {
await revalidateTag(tag);
res.status(200).json({ revalidated: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});Running in Standalone Scripts
To run a local sync script that updates your database and immediately refreshes the Dinou page cache:
// scripts/cron-sync.js
const { revalidateTag } = require("dinou/server");
async function run() {
console.log("Sincronizando base de datos...");
await syncDatabase();
console.log("Limpiando cache de productos...");
await revalidateTag("productos");
console.log("Proceso terminado.");
}
run().catch(console.error);Since standalone scripts execute outside the web server, you must run them with the Dinou loader and the React Server condition enabled:
node --conditions react-server --import ./dinou/core/register-loader.mjs scripts/cron-sync.js