Transform cached HTML
Sometimes you need to alter the HTML ISR handles, for example injecting a tracking script into pages served from cache, or stamping generated pages before they are stored. ISR exposes two hooks for this: modifyCachedHtml (runs on serve-from-cache, on every request) and modifyGeneratedHtml (runs once, on the fresh render, before the page is cached).
Which hook to pick: transform on serve when the change is per-request; transform on generate when it can be baked into the cached copy. See How ISR works for the serve-vs-generate split.
Preconditions
- A working ISR setup with an
ISRHandlerinstance and the serve/render middlewares wired.
Steps
Transform generated HTML by passing
modifyGeneratedHtmlon theISRHandlerconfig. It runs once, before the page is stored in the cache.server.tsconst isr = new ISRHandler({
indexHtml,
invalidateSecretToken: process.env['ISR_TOKEN'] ?? null,
enableLogging: true,
browserDistFolder,
bootstrap,
commonEngine,
modifyGeneratedHtml: (req, html) => `${html}<!-- Modified before caching -->`,
});Transform cached HTML by passing
modifyCachedHtmlon theserveFromCacheconfig. It runs on every cache hit, so keep the logic lightweight.server.tsserver.get('*', (req, res, next) =>
isr.serveFromCache(req, res, next, {
modifyCachedHtml: (req, cachedHtml) => `${cachedHtml}<!-- Served from cache, modified per request -->`,
}),
);
// Fresh render + cache write for cache misses:
server.get('*', (req, res, next) => isr.render(req, res, next));
Both hooks run inside the request path, and modifyCachedHtml runs on every serve. Heavy logic here increases response time.
Result
Pages served from the cache carry your per-request modifications, and freshly generated pages are stamped before they are stored, so the transformation is baked into every subsequent cache hit.
See also
- Reference:
modifyGeneratedHtmlfield onISRHandlerConfig·ModifyHtmlCallbackFn - Reference:
ServeFromCacheConfig.modifyCachedHtml