Skip to content

Commit e451815

Browse files
vtenfysGatsbyJS Bot
authored and
GatsbyJS Bot
committed
feat(gatsby-plugin-offline): "Magic" JS detection to make sites function correctly when JS is disabled retroactively (#17590)
* Set path resources on route update (for initial page load) * begin "magic" * refactor + fix always re-enabling * implement SW API route + only set head components for offline shell + misc * update snapshots * change messageapi back to a "normal" object * add comment re: syntax * rename back to original casing * add back noscript warning in default-html * restore snapshots
1 parent 547ce99 commit e451815

File tree

3 files changed

+56
-5
lines changed

3 files changed

+56
-5
lines changed

packages/gatsby-plugin-offline/src/gatsby-browser.js

+9
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,15 @@ function setPathResources(path, getResourceURLsForPathname) {
8181
exports.onRouteUpdate = ({ location, getResourceURLsForPathname }) => {
8282
const pathname = location.pathname.replace(__BASE_PATH__, ``)
8383
setPathResources(pathname, getResourceURLsForPathname)
84+
85+
if (
86+
`serviceWorker` in navigator &&
87+
navigator.serviceWorker.controller !== null
88+
) {
89+
navigator.serviceWorker.controller.postMessage({
90+
gatsbyApi: `enableOfflineShell`,
91+
})
92+
}
8493
}
8594

8695
exports.onPostPrefetchPathname = ({ pathname, getResourceURLsForPathname }) => {

packages/gatsby-plugin-offline/src/gatsby-ssr.js

+19
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import React from "react"
2+
13
export const onPreRenderHTML = ({
24
getHeadComponents,
35
pathname,
@@ -20,3 +22,20 @@ export const onPreRenderHTML = ({
2022

2123
replaceHeadComponents(filteredHeadComponents)
2224
}
25+
26+
export const onRenderBody = ({ pathname, setHeadComponents }) => {
27+
if (pathname !== `/offline-plugin-app-shell-fallback/`) {
28+
return
29+
}
30+
31+
setHeadComponents([
32+
<noscript key="disable-offline-shell">
33+
<link
34+
rel="preload"
35+
as="fetch"
36+
href="/.gatsby-plugin-offline:disableOfflineShell"
37+
/>
38+
<meta httpEquiv="refresh" content="0;url=" />
39+
</noscript>,
40+
])
41+
}

packages/gatsby-plugin-offline/src/sw-append.js

+28-5
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@
33
importScripts(`idb-keyval-iife.min.js`)
44

55
const { NavigationRoute } = workbox.routing
6+
let offlineShellEnabled = true
67

78
const navigationRoute = new NavigationRoute(async ({ event }) => {
9+
if (!offlineShellEnabled) {
10+
return await fetch(event.request)
11+
}
12+
813
let { pathname } = new URL(event.request.url)
914
pathname = pathname.replace(new RegExp(`^%pathPrefix%`), ``)
1015

@@ -31,17 +36,35 @@ const navigationRoute = new NavigationRoute(async ({ event }) => {
3136

3237
workbox.routing.registerRoute(navigationRoute)
3338

34-
const messageApi = {
35-
setPathResources(event, { path, resources }) {
39+
// prefer standard object syntax to support more browsers
40+
const MessageAPI = {
41+
setPathResources: (event, { path, resources }) => {
3642
event.waitUntil(idbKeyval.set(`resources:${path}`, resources))
3743
},
3844

39-
clearPathResources(event) {
45+
clearPathResources: event => {
4046
event.waitUntil(idbKeyval.clear())
4147
},
48+
49+
enableOfflineShell: () => {
50+
offlineShellEnabled = true
51+
},
52+
53+
disableOfflineShell: () => {
54+
offlineShellEnabled = false
55+
},
4256
}
4357

4458
self.addEventListener(`message`, event => {
45-
const { gatsbyApi } = event.data
46-
if (gatsbyApi) messageApi[gatsbyApi](event, event.data)
59+
const { gatsbyApi: api } = event.data
60+
if (api) MessageAPI[api](event, event.data)
61+
})
62+
63+
workbox.routing.registerRoute(/\/.gatsby-plugin-offline:.+/, ({ event }) => {
64+
const { pathname } = new URL(event.request.url)
65+
66+
const api = pathname.match(/:(.+)/)[1]
67+
MessageAPI[api]()
68+
69+
return new Response()
4770
})

0 commit comments

Comments
 (0)