Next.js Discord

Discord Forum

Implementing Full Route Caching and Revalidation at Runtime (Not Build Time) App router TS

Unanswered
Donskoy posted this in #help-forum
Open in Discord
DonskoyOP
## 🟢 How to Implement On-Demand Incremental Static Regeneration (ISR) for the Whole App ?

I'm working on a Next.js 15 + TypeScript app using the App Router. We have three deployment stages (dev, pre-prod, prod) and a single Docker build.

### ❓ How should we handle on demand static page generation?
- No Static Generation at Build Time: npm run build should NOT fetch data
- The first request generates the page and caches it indefinitely.
- Subsequent requests serve the cached page without hitting the API.
- Pages should revalidate via an /api/revalidate endpoint.

### 🛠️ Challenges & Questions
1️⃣ How to prevent data prefetching at build time?
2️⃣ Best approach to cache full routes post-initial request?
3️⃣ How to implement /api/revalidate to refresh specific pages?
4️⃣ Is Redis beneficial for ISR in a multi-instance setup?
5️⃣ Best practices for Docker env management across all stages?

### ✅ I need something for the whole app, similar to the code implementation of ISR for dynamic routes below[(All paths at runtime)](https://nextjs.org/docs/app/api-reference/functions/generate-static-params#all-paths-at-runtime)
export const revalidate = 31622400;
export const dynamicParams = true;
export async function generateStaticParams() {
  return [];
}

### Project Overview
- Stages: Development, Pre-prod, Production
- Data Source: Strapi v5 API
- Deployment: Single Docker build for all environments


🔗 Full Details : [Github](https://github.com/vercel/next.js/discussions/77139) | [V0.dev](https://v0.dev/chat/next-js-deployment-setup-HsguxXsUAAy?b=b_NAjnRiTEMrv)

13 Replies

Is any of this already working/in production so far?

Or are you only hypothetically asking what the outcome of implementing this structure would be?
@LuisLl Is any of this already working/in production so far? Or are you only hypothetically asking what the outcome of implementing this structure would be?
DonskoyOP
I was asking if is there any configuration to get following results

No Static Generation at Build Time: npm run build should NOT fetch data
The first request generates the page and caches it indefinitely.
Subsequent requests serve the cached page without hitting the API.
Pages should revalidate via an /api/revalidate endpoint.

Currently, I am using
export const dynamic = "force-dynamic"; in root layout
On each request API is hit & new page is rendered
This enables me to use single docker for 3 stages with revalide api logic (Working)

But here we have issue server load is increased. So I need to cache / store static page on 1st request & Subsequent requests serve the cached page without hitting the API. Data doesn't change frequently from Strapi. If changed revalidate is hit

my dockerfile
FROM --platform=linux/amd64 node:20-alpine AS builder
RUN apk add --no-cache libc6-compat

WORKDIR /app

ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}

COPY package.json package-lock.json ./

RUN npm ci --production --verbose --legacy-peer-deps

COPY . .

RUN npm run build

FROM node:20 AS runner
RUN apk add --no-cache nginx

WORKDIR /app

ENV NODE_ENV production
ENV PORT 3000
ENV HOSTNAME localhost

COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/next.config.js ./
COPY --from=builder /app/public ./public

COPY main-nginx.conf /etc/nginx/nginx.conf
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80 3000

CMD ["sh", "-c", "nginx && PORT=$PORT HOSTNAME=$HOSTNAME node server.js"]
Its a POC
@LuisLl Is any of this already working/in production so far? Or are you only hypothetically asking what the outcome of implementing this structure would be?
DonskoyOP
I’m asking hypothetically to explore what the outcome might be if we implemented this structure. No actual full fledged implementation is in place yet.
Okay, well the answer for the first two is [here in the docs](https://nextjs.org/docs/app/api-reference/functions/generate-static-params#all-paths-at-runtime)
1️⃣ How to prevent data prefetching at build time?
2️⃣ Best approach to cache full routes post-initial request?
Data won't be prefetched at build time and they'll be cached after the first time they're requested.

3️⃣ How to implement /api/revalidate to refresh specific pages?
Maybe call revalidatePath() with the specific page or slug you are trying to revalidate, send this path via searchParams to the /api/revalidate endpoint (/api/revalidate?pageToRevalidate=slug) or send it via the body along with a token that authorizes the user to perform the revalidation, since API handlers are public and exposed to everyone.
Do something like this:
// app/api/revalidate/route.ts
export async function POST(request: NextRequest) {
  const body = await request.json();
  // get the path & token
  // get the token and check against it  

  const pathToRevalidate = // get the specific path
  revalidatePath(pathToRevalidate);

  return NextResponse.json({revalidated : true});
}


I sadly don't have any suggestions for 4️⃣ and 5️⃣.
@Donskoy was it helpful?
DonskoyOP
Hi @LuisLl
Sorry for the late reply, I had a small accident.

This https://nextjs.org/docs/app/api-reference/functions/generate-static-params#all-paths-at-runtime is for ISR (with dynamic route segments).
But what about page.tsx .They will be built on build time (npm run build)

If I use force-dynamic, page will be SSR. On every request new page will be returned from server. Increasing server load.

I want to make page on on demand of 1st request
Cache it & store it as static page
After 1st req, all request will be server cached static page.

Same feature as ISR but for page.tsx
DonskoyOP
@LuisLl
Correct me if I am wrong

In Nextjs 15 App router

/app
/home
page.tsx
/products
/[id]
page.tsx <-- Uses generateStaticParams
page.tsx
layout.tsx
page.tsx


export async function generateStaticParams() {
return []; // no pre-rendered static paths on build time | all paths at run time
}
generateStaticParams is used with dynamic route segments for ISR.
Others pages don't have effect of generateStaticParams

What about home/page , products/page, root page.tsx?
@LuisLl
home/page , products/page, root page.tsx?

They will be built on build time (npm run build)

If I use force-dynamic, page will be SSR. On every request new page will be returned from server. Increasing server load.

I want to make page on on demand of 1st request
Cache it & store it as static page
After 1st req, all request will be server cached static page.

Same feature as ISR but for page.tsx
I see you want that behavior on your while app. Can I ask why don’t just pre-render home/page and the other ones that are similar?

I get the point for dynamic segments, where you won’t know the paths head of time but you still want to treat them as static and generate on demand the first time that route is requested, and then cached.
DonskoyOP
@LuisLl
I use Strapi CMS for content.
I have 3 stages dev, stagging, prod.

Each strapi cms instance in each stage may have different content.

I have to make 3 builds - each for one stage.

To deploy Nextjs App i will be dependent on Strapi & Backend to be deployed first.
Nextjs build will be needed to be started when both strapi, backend are deployed.
Things may break when strapi, backend new build are deployed & nextjs old build is there.
There will be down time.

So, I want to create a single build which can be used in all stages.
reducing number of build pipeline, release pipeline, time and storage for new build & down time.