workbox-sw: Google fonts not rendering when fully offline

Created on 2 Jul 2018  路  3Comments  路  Source: GoogleChrome/workbox

Library Affected:
workbox-sw (v3.3)

Browser & Platform:
Google Chrome on macOS High Sierra (10.13.5)

Issue or Feature Request Description:

(Repository to reproduce: https://github.com/caleb531/workbox-google-font-bug)

I am using Workbox's workbox-sw library to create a small service worker. I am trying to create a fully offline application, including serving my Google fonts when offline.

TL;DR

My Google fonts are not rendering offline because (for whatever reason) the font CSS is not cached by my service worker, though the font files are. This is preventing my Google fonts from rendering fully offline.

Long Story

I add the routing for Google fonts exactly as the homepage describes:

 workbox.routing.registerRoute(
  new RegExp('^https://fonts.(?:googleapis|gstatic).com/(.*)'),
  workbox.strategies.cacheFirst(),
); 

The CDN-served font files appear to be cached by my service worker, but not the CDN-served CSS. This is apparent when I activate Offline mode in the DevTools Network panel.

Network when online:
Network when online

Network when offline:
(notice the font failed to render):
Network when offline

Workbox debug in console:
(notice the font failed to render):
Workbox debug in console

My only suspicion is that this has to do with the private setting in the Cache-Control header for the CSS only (the fonts are public).

Google Font CSS response:
Google Font CSS response

Is this a bug? Is Workbox honoring cache-control: private? What can be done about this? It's the only obstacle keeping me from serving my app fully offline.

Thanks,
Caleb

P.S. Here's the HAR file too if it helps: localhost.har.zip

Most helpful comment

The Cache-Control: private doesn't come into play here.

The issue is almost certainly that the original CSS request was non-CORS, and that leads to an opaque response, which isn't cached when using a cache-first strategy by default.

We have a recipe specifically for dealing with this; here's a copy of it:

workbox.routing.registerRoute(
  new RegExp('https://fonts.(?:googleapis|gstatic).com/(.*)'),
  workbox.strategies.cacheFirst({
    cacheName: 'google-fonts',
    plugins: [
      new workbox.expiration.Plugin({
        maxEntries: 30,
      }),
      new workbox.cacheableResponse.Plugin({
        statuses: [0, 200]
      }),
    ],
  }),
);

All 3 comments

The Cache-Control: private doesn't come into play here.

The issue is almost certainly that the original CSS request was non-CORS, and that leads to an opaque response, which isn't cached when using a cache-first strategy by default.

We have a recipe specifically for dealing with this; here's a copy of it:

workbox.routing.registerRoute(
  new RegExp('https://fonts.(?:googleapis|gstatic).com/(.*)'),
  workbox.strategies.cacheFirst({
    cacheName: 'google-fonts',
    plugins: [
      new workbox.expiration.Plugin({
        maxEntries: 30,
      }),
      new workbox.cacheableResponse.Plugin({
        statuses: [0, 200]
      }),
    ],
  }),
);

@jeffposnick Thanks, that worked perfectly. I would ask that you please update the Google Fonts homepage example to match the recipe you gave, because it's otherwise misleading.

screen shot 2018-07-02 at 8 35 41 pm

Ah, thanks for catching that!

Was this page helpful?
0 / 5 - 0 ratings