If you want to only cache shell from prerendered SSR view with initial data you must provide two views:
/view-url
with data from SSR
/view-url?shell
with only shell version, without data (you can change logic from url-query to for example request header).
When user for the first time enter /view-url
you send 1. version and cache in Service Worker /view-url?shell
. When user come back to /view-url
you send him /view-url?shell
from Service Worker cache by doing something like this:
const CACHE_NAME = 'cache-token';
const staticUrlsToCache = ['/style.css', '/script.js', '/logo.png'];
const shellUrlsToCache = ['/view-url'];
const urlsToCache = [
...staticUrlsToCache,
shellUrlsToCache.map(url => `${url}?shell`),
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME).then(cache => cache.addAll(urlsToCache))
);
});
self.addEventListener('fetch', event => {
let request = event.request;
const shellUrl = shellUrlsToCache.find(url => request.url.endsWith(url));
if (shellUrl) {
// here is real magic!
request = new Request(`${shellUrl}?shell`);
}
event.respondWith(
caches.match(request).then(response => response || fetch(request))
);
});
The key point here is that you change original request /view-url
to /view-url?shell
in Service Worker!
If you want to read more about this technique I wrote an article about this problem How to combine PWA and isomorphic rendering (SSR)?