1
- // In production, we register a service worker to serve assets from local cache.
1
+ // This optional code is used to register a service worker.
2
+ // register() is not called by default.
2
3
3
4
// This lets the app load faster on subsequent visits in production, and gives
4
5
// it offline capabilities. However, it also means that developers (and users)
5
- // will only see deployed updates on the "N+1" visit to a page, since previously
6
- // cached resources are updated in the background.
6
+ // will only see deployed updates on subsequent visits to a page, after all the
7
+ // existing tabs open on the page have been closed, since previously cached
8
+ // resources are updated in the background.
7
9
8
- // To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
9
- // This link also includes instructions on opting out of this behavior.
10
+ // To learn more about the benefits of this model and instructions on how to
11
+ // opt-in, read http://bit.ly/CRA-PWA
10
12
11
13
const isLocalhost = Boolean (
12
14
window . location . hostname === 'localhost' ||
@@ -18,59 +20,74 @@ const isLocalhost = Boolean(
18
20
)
19
21
) ;
20
22
21
- export default function register ( ) {
23
+ export function register ( config ) {
22
24
if ( process . env . NODE_ENV === 'production' && 'serviceWorker' in navigator ) {
23
25
// The URL constructor is available in all browsers that support SW.
24
- const publicUrl = new URL ( process . env . PUBLIC_URL , window . location ) ;
26
+ const publicUrl = new URL ( process . env . PUBLIC_URL , window . location . href ) ;
25
27
if ( publicUrl . origin !== window . location . origin ) {
26
28
// Our service worker won't work if PUBLIC_URL is on a different origin
27
29
// from what our page is served on. This might happen if a CDN is used to
28
- // serve assets; see https://github.com/facebookincubator /create-react-app/issues/2374
30
+ // serve assets; see https://github.com/facebook /create-react-app/issues/2374
29
31
return ;
30
32
}
31
33
32
34
window . addEventListener ( 'load' , ( ) => {
33
35
const swUrl = `${ process . env . PUBLIC_URL } /service-worker.js` ;
34
36
35
37
if ( isLocalhost ) {
36
- // This is running on localhost. Lets check if a service worker still exists or not.
37
- checkValidServiceWorker ( swUrl ) ;
38
+ // This is running on localhost. Let's check if a service worker still exists or not.
39
+ checkValidServiceWorker ( swUrl , config ) ;
38
40
39
41
// Add some additional logging to localhost, pointing developers to the
40
42
// service worker/PWA documentation.
41
43
navigator . serviceWorker . ready . then ( ( ) => {
42
44
console . log (
43
45
'This web app is being served cache-first by a service ' +
44
- 'worker. To learn more, visit https ://goo.gl/SC7cgQ '
46
+ 'worker. To learn more, visit http ://bit.ly/CRA-PWA '
45
47
) ;
46
48
} ) ;
47
49
} else {
48
- // Is not local host . Just register service worker
49
- registerValidSW ( swUrl ) ;
50
+ // Is not localhost . Just register service worker
51
+ registerValidSW ( swUrl , config ) ;
50
52
}
51
53
} ) ;
52
54
}
53
55
}
54
56
55
- function registerValidSW ( swUrl ) {
57
+ function registerValidSW ( swUrl , config ) {
56
58
navigator . serviceWorker
57
59
. register ( swUrl )
58
60
. then ( registration => {
59
61
registration . onupdatefound = ( ) => {
60
62
const installingWorker = registration . installing ;
63
+ if ( installingWorker == null ) {
64
+ return ;
65
+ }
61
66
installingWorker . onstatechange = ( ) => {
62
67
if ( installingWorker . state === 'installed' ) {
63
68
if ( navigator . serviceWorker . controller ) {
64
- // At this point, the old content will have been purged and
65
- // the fresh content will have been added to the cache.
66
- // It's the perfect time to display a "New content is
67
- // available; please refresh." message in your web app.
68
- console . log ( 'New content is available; please refresh.' ) ;
69
+ // At this point, the updated precached content has been fetched,
70
+ // but the previous service worker will still serve the older
71
+ // content until all client tabs are closed.
72
+ console . log (
73
+ 'New content is available and will be used when all ' +
74
+ 'tabs for this page are closed. See http://bit.ly/CRA-PWA.'
75
+ ) ;
76
+
77
+ // Execute callback
78
+ if ( config && config . onUpdate ) {
79
+ config . onUpdate ( registration ) ;
80
+ }
69
81
} else {
70
82
// At this point, everything has been precached.
71
83
// It's the perfect time to display a
72
84
// "Content is cached for offline use." message.
73
85
console . log ( 'Content is cached for offline use.' ) ;
86
+
87
+ // Execute callback
88
+ if ( config && config . onSuccess ) {
89
+ config . onSuccess ( registration ) ;
90
+ }
74
91
}
75
92
}
76
93
} ;
@@ -81,14 +98,15 @@ function registerValidSW(swUrl) {
81
98
} ) ;
82
99
}
83
100
84
- function checkValidServiceWorker ( swUrl ) {
101
+ function checkValidServiceWorker ( swUrl , config ) {
85
102
// Check if the service worker can be found. If it can't reload the page.
86
103
fetch ( swUrl )
87
104
. then ( response => {
88
105
// Ensure service worker exists, and that we really are getting a JS file.
106
+ const contentType = response . headers . get ( 'content-type' ) ;
89
107
if (
90
108
response . status === 404 ||
91
- response . headers . get ( 'content-type' ) . indexOf ( 'javascript' ) === - 1
109
+ ( contentType != null && contentType . indexOf ( 'javascript' ) === - 1 )
92
110
) {
93
111
// No service worker found. Probably a different app. Reload the page.
94
112
navigator . serviceWorker . ready . then ( registration => {
@@ -98,7 +116,7 @@ function checkValidServiceWorker(swUrl) {
98
116
} ) ;
99
117
} else {
100
118
// Service worker found. Proceed as normal.
101
- registerValidSW ( swUrl ) ;
119
+ registerValidSW ( swUrl , config ) ;
102
120
}
103
121
} )
104
122
. catch ( ( ) => {
0 commit comments