I’m implementing caching in a create-vite-extra project using lru-cache. My goal is to cache rendered HTML and serve it from the cache when available. The cache is defined and used in the *all route handler as shown below:
// server/app.ts
const cache = new LRUCache({
ttl: 1000 * 60 * 60,
max: 100,
});
In the *all handler, I check if the cache has the requested URL and return the cached HTML if available. Otherwise, I render the app, save the output to the cache, and send it to the client:
if (cache.has(url)) {
res.set({'Content-Type': 'text/html'});
res.end(cache.get(url));
return;
}
const {pipe, abort} = render(
url,
queryClient,
dehydratedState,
{
onShellReady() {
res.status(200);
res.set({'Content-Type': 'text/html'});
const transformStream = new Transform({
transform(chunk, encoding, callback) {
res.write(chunk, encoding);
callback();
},
});
const [htmlStart, htmlEnd] = template.split(`<!--app-html-->`);
res.write(htmlStart);
transformStream.on('finish', () => {
cache.set(url, htmlStart + htmlEnd);
res.end(htmlEnd);
});
pipe(transformStream);
},
// ...
}
);
The issue is that when I run the app, the browser renders the app’s state (window.REACT_QUERY_STATE) instead of the actual HTML. The rendered page looks incomplete or broken.
I’m not sure if the problem is with:
How the HTML template is being processed (template.split or vite.transformIndexHtml).
The caching logic (cache.set storing incomplete/incorrect content).
How the React Query state (window.REACT_QUERY_STATE) is being injected.
Has anyone faced a similar issue or knows how to fix this?
Mahesa Bima Wijaya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.