title: I want my CRA PWA to fetch from cache only if there is no internet. Basically I want it to be a Network First approach
body: <p>Attaching my service worker files and package.json.
  I think I'm missing a step here, otherwise this should have worked.
  I don't know what else to add here. This should have worked. I even keep clearing all data from my browser, so that the service workers keep updating. But when I open the website, it still shows me the last version of the website, not the latest version.</p>
  <p>sw-custom.js</p>
  <pre><code>if (typeof importScripts === &quot;function&quot;) {
    importScripts(
      &quot;https://storage.googleapis.com/workbox-cdn/releases/5.0.0/workbox-sw.js&quot;
    );
    /* global workbox */
    if (workbox) {
      console.log(&quot;Workbox is loaded&quot;);
      workbox.core.skipWaiting();
  
      /* injection point for manifest files.  */
      workbox.precaching.precacheAndRoute([]);
      /* custom cache rules */
      workbox.routing.registerRoute(
        new workbox.routing.NavigationRoute(new workbox.strategies.NetworkOnly())
      );
    } else {
      console.log(&quot;Workbox could not be loaded. No Offline support&quot;);
    }
  }
  
  </code></pre>
  <p>sw-build.js</p>
  <pre><code>const workboxBuild = require(&quot;workbox-build&quot;);
  
  const buildSW = () =&gt; {
    // The build is expected to fail if the
    // sw install rules couldn't be generated.
    // Add a catch block to handle this scenario.
    return workboxBuild
      .injectManifest({
        swSrc: &quot;src/sw-custom.js&quot;, // custom sw rule
  
        swDest: &quot;build/sw.js&quot;, // sw output file (auto-generated
  
        globDirectory: &quot;build&quot;,
  
        globPatterns: [&quot;**/*.{js,css,html,png,svg}&quot;],
  
        maximumFileSizeToCacheInBytes: 10 * 1024 * 1024,
      })
      .then(({ count, size, warnings }) =&gt; {
        warnings.forEach(console.warn);
        console.info(`${count} files will be precached,
                    totaling ${size / (1024 * 1024)} MBs.`);
      });
  };
  
  buildSW();
  
  </code></pre>
  <p>serviceWorker.js</p>
  <pre><code>// This optional code is used to register a service worker.
  // register() is not called by default.
  
  import { ACTIONS } from &quot;./utils/actions&quot;;
  import { store } from &quot;./utils/configureStore&quot;;
  
  // This lets the app load faster on subsequent visits in production, and gives
  // it offline capabilities. However, it also means that developers (and users)
  // will only see deployed updates on subsequent visits to a page, after all the
  // existing tabs open on the page have been closed, since previously cached
  // resources are updated in the background.
  
  // To learn more about the benefits of this model and instructions on how to
  // opt-in, read -PWA
  
  const isLocalhost = Boolean(
    window.location.hostname === &quot;localhost&quot; ||
      // [::1] is the IPv6 localhost address.
      window.location.hostname === &quot;[::1]&quot; ||
      // 127.0.0.1/8 is considered localhost for IPv4.
      window.location.hostname.match(
        /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
      )
  );
  
  export function register(config) {
    if (process.env.NODE_ENV === &quot;production&quot; &amp;&amp; &quot;serviceWorker&quot; in navigator) {
      // The URL constructor is available in all browsers that support SW.
      const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
      if (publicUrl.origin !== window.location.origin) {
        // Our service worker won't work if PUBLIC_URL is on a different origin
        // from what our page is served on. This might happen if a CDN is used to
        // serve assets; see https://github.com/facebook/create-react-app/issues/2374
        return;
      }
      window.addEventListener(&quot;load&quot;, () =&gt; {
        // const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
  
        const swUrl = `${process.env.PUBLIC_URL}/sw.js`;
  
        if (isLocalhost) {
          // This is running on localhost. Let's check if a service worker still exists or not.
          checkValidServiceWorker(swUrl, config);
  
          // Add some additional logging to localhost, pointing developers to the
          // service worker/PWA documentation.
          navigator.serviceWorker.ready.then(() =&gt; {
            console.log(
              &quot;This web app is being served cache-first by a service &quot; +
                &quot;worker. To learn more, visit -PWA&quot;
            );
          });
        } else {
          // Is not localhost. Just register service worker
          registerValidSW(swUrl, config);
        }
      });
    }
  }
  
  function registerValidSW(swUrl, config) {
    navigator.serviceWorker
      .register(swUrl)
      .then((registration) =&gt; {
        registration.onupdatefound = () =&gt; {
          const installingWorker = registration.installing;
          if (installingWorker == null) {
            return;
          }
          installingWorker.onstatechange = () =&gt; {
            if (installingWorker.state === &quot;installed&quot;) {
              if (navigator.serviceWorker.controller) {
                // At this point, the updated precached content has been fetched,
                // but the previous service worker will still serve the older
                // content until all client tabs are closed.
                console.log(
                  &quot;New content is available and will be used when all &quot; +
                    &quot;tabs for this page are closed. See -PWA.&quot;
                );
  
                // Execute callback
                if (config &amp;&amp; config.onUpdate) {
                  config.onUpdate(registration);
                }
              } else {
                // At this point, everything has been precached.
                // It's the perfect time to display a
                // &quot;Content is cached for offline use.&quot; message.
                console.log(&quot;Content is cached for offline use.&quot;);
  
                // Execute callback
                if (config &amp;&amp; config.onSuccess) {
                  config.onSuccess(registration);
                }
              }
            }
          };
        };
      })
      .catch((error) =&gt; {
        console.error(&quot;Error during service worker registration:&quot;, error);
      });
  }
  
  function checkValidServiceWorker(swUrl, config) {
    // Check if the service worker can be found. If it can't reload the page.
    fetch(swUrl)
      .then((response) =&gt; {
        // Ensure service worker exists, and that we really are getting a JS file.
        const contentType = response.headers.get(&quot;content-type&quot;);
        if (
          response.status === 404 ||
          (contentType != null &amp;&amp; contentType.indexOf(&quot;javascript&quot;) === -1)
        ) {
          // No service worker found. Probably a different app. Reload the page.
          navigator.serviceWorker.ready.then((registration) =&gt; {
            registration.unregister().then(() =&gt; {
              window.location.reload();
            });
          });
        } else {
          // Service worker found. Proceed as normal.
          registerValidSW(swUrl, config);
        }
      })
      .catch(() =&gt; {
        console.log(
          &quot;No internet connection found. App is running in offline mode.&quot;
        );
      });
  }
  
  export function unregister() {
    if (&quot;serviceWorker&quot; in navigator) {
      navigator.serviceWorker.ready.then((registration) =&gt; {
        registration.unregister();
      });
    }
  }
  register();
  
  </code></pre>
  <p>package.json</p>
  <pre><code>{
    &quot;name&quot;: &quot;admin&quot;,
    &quot;version&quot;: &quot;0.1.0&quot;,
    &quot;private&quot;: true,
    &quot;dependencies&quot;: {
      &quot;@date-io/date-fns&quot;: &quot;^1.3.9&quot;,
      &quot;@date-io/moment&quot;: &quot;^2.4.0&quot;,
      &quot;@devexpress/dx-react-chart&quot;: &quot;^2.6.2&quot;,
      &quot;@devexpress/dx-react-chart-bootstrap4&quot;: &quot;^2.6.2&quot;,
      &quot;@devexpress/dx-react-chart-material-ui&quot;: &quot;^2.6.2&quot;,
      &quot;@devexpress/dx-react-core&quot;: &quot;^2.6.2&quot;,
      &quot;@devexpress/dx-react-scheduler&quot;: &quot;^2.5.0&quot;,
      &quot;@devexpress/dx-react-scheduler-material-ui&quot;: &quot;^2.5.0&quot;,
      &quot;@material-ui/core&quot;: &quot;^4.3.1&quot;,
      &quot;@material-ui/icons&quot;: &quot;^4.2.1&quot;,
      &quot;@material-ui/lab&quot;: &quot;^4.0.0-alpha.24&quot;,
      &quot;@material-ui/pickers&quot;: &quot;^3.2.4&quot;,
      &quot;@material-ui/styles&quot;: &quot;^4.3.0&quot;,
      &quot;@uppy/core&quot;: &quot;^1.2.0&quot;,
      &quot;@uppy/react&quot;: &quot;^1.2.0&quot;,
      &quot;antd&quot;: &quot;^3.22.2&quot;,
      &quot;antd-mobile&quot;: &quot;^2.3.1&quot;,
      &quot;axios&quot;: &quot;^0.19.2&quot;,
      &quot;braft-editor&quot;: &quot;^2.3.9&quot;,
      &quot;clsx&quot;: &quot;^1.1.0&quot;,
      &quot;connected-react-router&quot;: &quot;^6.5.2&quot;,
      &quot;date-fns&quot;: &quot;^2.0.0-beta.5&quot;,
      &quot;firebase&quot;: &quot;^6.3.4&quot;,
      &quot;localforage&quot;: &quot;^1.7.3&quot;,
      &quot;lodash&quot;: &quot;^4.17.15&quot;,
      &quot;material-table&quot;: &quot;^1.57.2&quot;,
      &quot;moment&quot;: &quot;^2.24.0&quot;,
      &quot;notistack&quot;: &quot;^0.8.9&quot;,
      &quot;qs&quot;: &quot;^6.9.3&quot;,
      &quot;react&quot;: &quot;^16.8.6&quot;,
      &quot;react-dom&quot;: &quot;^16.8.6&quot;,
      &quot;react-firebaseui&quot;: &quot;^4.0.0&quot;,
      &quot;react-geocode&quot;: &quot;^0.2.1&quot;,
      &quot;react-geosuggest&quot;: &quot;^2.13.0&quot;,
      &quot;react-google-maps&quot;: &quot;^9.4.5&quot;,
      &quot;react-helmet&quot;: &quot;^5.2.1&quot;,
      &quot;react-mentions&quot;: &quot;^3.3.1&quot;,
      &quot;react-redux&quot;: &quot;^7.1.0&quot;,
      &quot;react-router-dom&quot;: &quot;^5.0.1&quot;,
      &quot;react-scripts&quot;: &quot;3.0.1&quot;,
      &quot;react-virtualized&quot;: &quot;^9.21.2&quot;,
      &quot;redux&quot;: &quot;^4.0.4&quot;,
      &quot;redux-persist&quot;: &quot;^5.10.0&quot;,
      &quot;redux-thunk&quot;: &quot;^2.3.0&quot;,
      &quot;styled-components&quot;: &quot;^4.3.2&quot;,
      &quot;tabletop&quot;: &quot;^1.6.2&quot;,
      &quot;uppy&quot;: &quot;^1.3.0&quot;,
      &quot;uuid&quot;: &quot;^3.3.2&quot;
    },
    &quot;devDependencies&quot;: {
      &quot;babel-plugin-import&quot;: &quot;^1.12.0&quot;,
      &quot;customize-cra&quot;: &quot;^0.5.0&quot;,
      &quot;husky&quot;: &quot;^3.0.2&quot;,
      &quot;jest-dom&quot;: &quot;^4.0.0&quot;,
      &quot;jest-enzyme&quot;: &quot;^7.0.2&quot;,
      &quot;less&quot;: &quot;^3.10.2&quot;,
      &quot;less-loader&quot;: &quot;^5.0.0&quot;,
      &quot;lint-staged&quot;: &quot;^9.2.1&quot;,
      &quot;prettier&quot;: &quot;^1.18.2&quot;,
      &quot;react-app-rewired&quot;: &quot;^2.1.3&quot;,
      &quot;react-testing-library&quot;: &quot;^8.0.1&quot;,
      &quot;redux-devtools-extension&quot;: &quot;^2.13.8&quot;,
      &quot;redux-logger&quot;: &quot;^3.0.6&quot;,
      &quot;source-map-explorer&quot;: &quot;^2.0.1&quot;
    },
    &quot;scripts&quot;: {
      &quot;build-sw&quot;: &quot;node ./src/sw-build.js&quot;,
      &quot;clean-cra-sw&quot;: &quot;rm -f build/precache-manifest.*.js &amp;&amp; rm -f build/service-worker.js&quot;,
      &quot;analyze&quot;: &quot;source-map-explorer 'build/static/js/*.js'&quot;,
      &quot;start&quot;: &quot;PORT=3002 react-app-rewired start&quot;,
      &quot;build&quot;: &quot;react-app-rewired build &amp;&amp; npm run build-sw &amp;&amp; npm run clean-cra-sw&quot;,
      &quot;test&quot;: &quot;react-app-rewired test&quot;,
      &quot;eject&quot;: &quot;react-scripts eject&quot;
    },
    &quot;eslintConfig&quot;: {
      &quot;extends&quot;: &quot;react-app&quot;
    },
    &quot;browserslist&quot;: {
      &quot;production&quot;: [
        &quot;&gt;0.2%&quot;,
        &quot;not dead&quot;,
        &quot;not op_mini all&quot;
      ],
      &quot;development&quot;: [
        &quot;last 1 chrome version&quot;,
        &quot;last 1 firefox version&quot;,
        &quot;last 1 safari version&quot;
      ]
    }
  }
  </code></pre>
  <p>Can someone please tell me if I'm missing something here?</p>