'How does SSR go with PWA
How can one do SSR (Server side rendering) with PWA (Progressive web app)?
From what I understand,
SSR
The SSR runtime will load the page and run the necessary scripts to load the data on to the page. Then returns the rendered html. This is important for web crawlers which will not run javascript and browsers with no-script. At least the first impression will be usable.
PWA
Among others, PWA requires having a shell, which will be cached and the data will come after it. This means, even if the user is offline, the shell will be loaded.
?
So, if we're pre rendering the data, how can one cache the shell separate from the data?
Solution 1:[1]
If you want to only cache shell from prerendered SSR view with initial data you must provide two views:
/view-urlwith data from SSR/view-url?shellwith 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)?
Solution 2:[2]
The strategy is to serve the first page loading using SSR and all following page navigations using the cached app shell. SSR returns different html for different pages, so we can specify a special path like /app-shell to fetch a skeleton html for client side rendering.
If you want to learn more about it, you can refer to my article How To Turn a Server-Side-Rendered React SPA Into a PWA.
Solution 3:[3]
You should use workbox library by google - look at these docs on how to cache routes by using the workbox-routing module.
Here are also some common recipes or approaches to handle caching in any type of a web app.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Everettss |
| Solution 2 | Kanqiang Sun |
| Solution 3 | Maye Edwin |
