English | 简体中文
A On-Demand Incremental Static Regeneration (ISR) template built with the Next.js App Router, deployed on EdgeOne Makers.
The page is statically cached — every visit returns the same "generated time". The page is only re-generated (and the time updated) after you call the revalidation endpoint.
- Features
- Tech Stack
- Getting Started
- How It Works
- API
- Verifying ISR
- Deployment
- Environment Variables
- Project Structure
- License
- ⚡️ On-demand ISR — precisely refresh page cache via
revalidatePath/revalidateTag - 🔌 Revalidation endpoint — both
GET(triggerable straight from the browser) andPOST, with optional secret auth - 🧪 Visual demo — the home page shows a "generated time" plus a one-click trigger button to verify ISR at a glance
- Next.js 15 (App Router)
- React 19
- TypeScript
- EdgeOne Makers (deployment platform)
- Node.js ≥ 18
- npm (or pnpm / yarn)
npm install
npm run dev # http://localhost:3000
⚠️ Dev mode (next dev) does not cache — the time changes on every refresh, so you won't see the ISR effect. To verify ISR, use a production build (below).
npm run build
npm start- The home page
app/page.tsxusesexport const revalidate = 31536000(a large value), making it an ISR page (rendered by the SSR function), so it can be regenerated on demand byrevalidatePath. Do not useforce-static. - The revalidation endpoint
app/api/revalidate/route.tscallsrevalidatePath/revalidateTag.
| Method | Path | Description |
|---|---|---|
GET |
/api/revalidate?path=/ |
Revalidate by path (can be triggered directly in the browser) |
GET |
/api/revalidate?tag=<tag> |
Revalidate by tag |
POST |
/api/revalidate |
Body: { "paths": ["/"], "tags": [] } |
Auth is optional: when REVALIDATE_SECRET is set, requests must include the x-revalidate-secret header (GET can also use ?secret=); if unset, no check is performed. The home page button reads the secret from NEXT_PUBLIC_REVALIDATE_SECRET.
npm run build && npm start
# 1) Refresh twice — the timestamp is identical (cache hit)
curl -s localhost:3000/ | grep -oE '[0-9T:.-]{20,}Z'
curl -s localhost:3000/ | grep -oE '[0-9T:.-]{20,}Z'
# 2) Trigger revalidation
curl -s "localhost:3000/api/revalidate?path=/"
# 3) Refresh again — the timestamp changed = it works
curl -s localhost:3000/ | grep -oE '[0-9T:.-]{20,}Z'When verifying on EdgeOne, use curl (a browser soft refresh may hit the RSC / browser cache and show a stale value). CDN purge is asynchronous, so the first request may still be stale — just refresh once more. On a distributed CDN, different edge nodes may each cache their own regenerated copy, so the timestamp can alternate between a few values — this is expected.
edgeone makers build
edgeone makers deployFor auth, configure the environment variable REVALIDATE_SECRET (and NEXT_PUBLIC_REVALIDATE_SECRET for the home page button — the two must match) in the EdgeOne console.
| Variable | Required | Description |
|---|---|---|
REVALIDATE_SECRET |
No | Secret for the revalidation endpoint; when set, the endpoint enforces it |
NEXT_PUBLIC_REVALIDATE_SECRET |
No | Secret sent by the home page button; must match the one above |
app/
page.tsx # Home page (ISR, shows the generated time)
revalidate-button.tsx # Button that triggers revalidation (client component)
api/revalidate/route.ts # Revalidation endpoint (GET / POST)
layout.tsx # Root layout
not-found.tsx # 404 page
page.module.css # Home page styles
styles/
globals.css # Global theme
next.config.ts