Making a Progressive Web App

The production build has all the tools necessary to generate a first-classProgressive Web App,but the offline/cache-first behavior is opt-in only. By default,the build process will generate a service worker file, but it will not beregistered, so it will not take control of your production web app.

In order to opt-in to the offline-first behavior, developers should look for thefollowing in their src/index.js file:

  1. // If you want your app to work offline and load faster, you can change
  2. // unregister() to register() below. Note this comes with some pitfalls.
  3. // Learn more about service workers: https://bit.ly/CRA-PWA
  4. serviceWorker.unregister();

As the comment states, switching serviceWorker.unregister() toserviceWorker.register() will opt you in to using the service worker.

Why Opt-in?

Offline-first Progressive Web Apps are faster and more reliable than traditional web pages, and provide an engaging mobile experience:

  • All static site assets are cached so that your page loads fast on subsequent visits, regardless of network connectivity (such as 2G or 3G). Updates are downloaded in the background.
  • Your app will work regardless of network state, even if offline. This means your users will be able to use your app at 10,000 feet and on the subway.
  • On mobile devices, your app can be added directly to the user's home screen, app icon and all. This eliminates the need for the app store.However, they can make debugging deployments more challenging so, starting with Create React App 2, service workers are opt-in.

The workbox-webpack-pluginis integrated into production configuration,and it will take care of generating a service worker file that will automaticallyprecache all of your local assets and keep them up to date as you deploy updates.The service worker will use a cache-first strategyfor handling all requests for local assets, includingnavigation requestsfor your HTML, ensuring that your web app is consistently fast, even on a slowor unreliable network.

Offline-First Considerations

If you do decide to opt-in to service worker registration, please take thefollowing into account:

  • After the initial caching is done, the service worker lifecyclecontrols when updated content ends up being shown to users. In order to guard againstrace conditions with lazy-loaded content,the default behavior is to conservatively keep the updated service worker in the "waiting"state. This means that users will end up seeing older content until they close (reloading is notenough) their existing, open tabs. See this blog postfor more details about this behavior.

  • Users aren't always familiar with offline-first web apps. It can be useful tolet the user knowwhen the service worker has finished populating your caches (showing a "This webapp works offline!" message) and also let them know when the service worker hasfetched the latest updates that will be available the next time they load thepage (showing a "New content is available once existing tabs are closed." message). Showingthese messages is currently left as an exercise to the developer, but as astarting point, you can make use of the logic included in src/serviceWorker.js, whichdemonstrates which service worker lifecycle events to listen for to detect eachscenario, and which as a default, just logs appropriate messages to theJavaScript console.

  • Service workers require HTTPS,although to facilitate local testing, that policydoes not apply to localhost.If your production web server does not support HTTPS, then the service workerregistration will fail, but the rest of your web app will remain functional.

  • The service worker is only enabled in the production environment,e.g. the output of npm run build. It's recommended that you do not enable anoffline-first service worker in a development environment, as it can lead tofrustration when previously cached assets are used and do not include the latestchanges you've made locally.

  • If you need to test your offline-first service worker locally, buildthe application (using npm run build) and run a simple http server from yourbuild directory. After running the build script, create-react-app will giveinstructions for one way to test your production build locally and the deployment instructions haveinstructions for using other methods. Be sure to always use anincognito window to avoid complications with your browser cache.

  • By default, the generated service worker file will not intercept or cache anycross-origin traffic, like HTTP API requests,images, or embeds loaded from a different domain.

Progressive Web App Metadata

The default configuration includes a web app manifest located atpublic/manifest.json, that you can customize withdetails specific to your web application.

When a user adds a web app to their homescreen using Chrome or Firefox onAndroid, the metadata in manifest.json determines whaticons, names, and branding colors to use when the web app is displayed.The Web App Manifest guideprovides more context about what each field means, and how your customizationswill affect your users' experience.

Progressive web apps that have been added to the homescreen will load faster andwork offline when there's an active service worker. That being said, themetadata from the web app manifest will still be used regardless of whether ornot you opt-in to service worker registration.