React Weather App: Progressive Web App

npx create-react-app weather-app
cd weather-app
var CACHE_NAME = 'weather-app';var urlsToCache = ['/','/completed'];// Install a service workerthis.addEventListener('install', event => {// Perform install stepsevent.waitUntil(caches.open(CACHE_NAME).then(function(cache) {console.log('Opened cache');return cache.addAll(urlsToCache);}));});// Cache and return requeststhis.addEventListener('fetch', event => {event.respondWith(caches.match(event.request).then(function(response) {// Cache hit - return responseif (response) {return response;}return fetch(event.request);}));});// Update a service workerthis.addEventListener('activate', event => {var cacheWhitelist = ['pwa-weather-app'];event.waitUntil(caches.keys().then(cacheNames => {return Promise.all(cacheNames.map(cacheName => {if (cacheWhitelist.indexOf(cacheName) === -1) {return caches.delete(cacheName);}}));}));});
// This optional code is used to register a service worker.// register() is not called by default.// 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 http://bit.ly/CRA-PWAconst isLocalhost = Boolean(window.location.hostname === 'localhost' ||// [::1] is the IPv6 localhost address.window.location.hostname === '[::1]' ||// 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 === 'production' && 'serviceWorker' 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/2374return;}window.addEventListener('load', () => {const swUrl = `${process.env.PUBLIC_URL}/service-worker.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(() => {console.log('This web app is being served cache-first by a service ' +'worker. To learn more, visit http://bit.ly/CRA-PWA');});} else {// Is not localhost. Just register service workerregisterValidSW(swUrl, config);}});}}function registerValidSW(swUrl, config) {navigator.serviceWorker.register(swUrl).then(registration => {registration.onupdatefound = () => {const installingWorker = registration.installing;if (installingWorker == null) {return;}installingWorker.onstatechange = () => {if (installingWorker.state === 'installed') {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('New content is available and will be used when all ' +'tabs for this page are closed. See http://bit.ly/CRA-PWA.');// Execute callbackif (config && config.onUpdate) {config.onUpdate(registration);}} else {// At this point, everything has been precached.// It's the perfect time to display a// "Content is cached for offline use." message.console.log('Content is cached for offline use.');// Execute callbackif (config && config.onSuccess) {config.onSuccess(registration);}}}};};}).catch(error => {console.error('Error during service worker registration:', error);});}function checkValidServiceWorker(swUrl, config) {// Check if the service worker can be found. If it can't reload the page.fetch(swUrl).then(response => {// Ensure service worker exists, and that we really are getting a JS file.const contentType = response.headers.get('content-type');if (response.status === 404 ||(contentType != null && contentType.indexOf('javascript') === -1)) {// No service worker found. Probably a different app. Reload the page.navigator.serviceWorker.ready.then(registration => {registration.unregister().then(() => {window.location.reload();});});} else {// Service worker found. Proceed as normal.registerValidSW(swUrl, config);}}).catch(() => {console.log('No internet connection found. App is running in offline mode.');});}export function unregister() {if ('serviceWorker' in navigator) {navigator.serviceWorker.ready.then(registration => {registration.unregister();});}}
import * as serviceWorker from './serviceWorker';serviceWorker.register();
<script>if ('serviceWorker' in navigator) {window.addEventListener('load', function() {navigator.serviceWorker.register('worker.js').then(function(registration) {console.log('Worker registration successful', registration.scope);}, function(err) {console.log('Worker registration failed', err);}).catch(function(err) {console.log(err);});});} else {console.log('Service Worker is not supported by browser.');}</script>
{"src": "logo512.png","type": "image/png","sizes": "512x512"}

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store