6

So lets say you have a React-based mobile web app, that takes advantage of server-side rendering for the initial view ( for speed + SEO reasons ). There is no "index.html" file - the index file is dynamically built server-side and returned in the initial response.

Now lets say you want to add PWA functionality to that app. You hook up a service worker to cache assets, etc.

One of the core tenants of PWA's is that they provide an offline experience. Say we just want to show a refresh page, "You're offline, click here to refresh", when the service worker detects the user is offline.

Online examples provided by google talk about using an App Shell -- a static HTML file, which can be cached by the service worker on initial visit, and which will be the "shell" your react app lives inside. This shell ties in to showing an "offline" view.

How does this work with server-side rendering, where there is no "shell" html file, and each route can potentially return a different index.html file?

Any demos or examples of this functionality in the wild?

tdc
  • 5,174
  • 12
  • 53
  • 102

1 Answers1

4

Any demos or examples of this functionality in the wild?

Yes!

Take a look at https://github.com/GoogleChrome/sw-precache/tree/master/app-shell-demo, which uses the dynamicUrlToDepndencies option in sw-precache to define which underlying resources are used to server-render the App Shell HTML.

The service worker it generates will take care of updating the App Shell HTML whenever any of the resources it depends on changes.

In this model the service worker will return the same App Shell HTML document for all navigation requests, so it assumes that the App Shell HTML is generic enough to then be populated at runtime with the dynamic content that's associated with the actual URL via your standard client-side routing logic.

Jeff Posnick
  • 53,580
  • 14
  • 141
  • 167
  • Hi Jeff! Thanks so much for replying. I've read through a lot of your code and it's great to have your input and feedback! :) so in my scenario, we have a `PageTemplate.js` which is more or less the equivalent of what our shell would be -- basically a function that runs server-side & returns a large template string of the initial page markup. Is that what I'd want to pass in to `dynamicUrlToDependencies`? I'm still getting up to speed on PWA's so apologies if this is a silly question. In your example, it seems like it'd only cache for the `/shell` route specifically? – tdc Apr 26 '17 at 22:28
  • Right, if the contents of `/shell` are uniquely determined by the contents `PageTemplate.js`, then that's what you'd list in `dynamicUrlToDependencies`. If `PageTemplate.js` loads another external resource (like a `.hbs`) then you'd list that, too. The other part of the setup would be to use `navigateFallback: '/shell` to cause all navigation results (regardless of the actual URL) to be fulfilled with your cached `/shell`. – Jeff Posnick Apr 26 '17 at 22:56
  • Hi Jeff - Do you mind elaborating on "if [it] loads another external resource"? Do you mean loads during the build compilation, or literally loads asynchronously in the browser? In my (react/redux/react-router) app, data is fetched from an API on the server, a redux store generated, and various actions dispatched to that store before serving the contents of PageTemplate to the user -- pageTemplate is populated with the markup for the initial render of that route. Presumably I would add a route specifically for the app shell, and tell SW to pre-cache the resources for that route? – tdc Apr 27 '17 at 14:56
  • It's hard to say exactly what setup you'd need, especially in the space allowed here. Can you share a link to your source code, if it's open sourced? Or a subset of the source in a gist? I can make a more informed comment based on that. – Jeff Posnick Apr 27 '17 at 15:17
  • Hey @Jeff - Thanks for the help, I opened an issue on the github repo (with some code samples) for a bit easier longform discussion - https://github.com/GoogleChrome/sw-precache/issues/288 Thanks! – tdc Apr 28 '17 at 16:59