Skip to content

Commit

Permalink
feat(gatsby-plugin-offline): "Magic" JS detection to make sites funct…
Browse files Browse the repository at this point in the history
…ion 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
  • Loading branch information
vtenfys authored and GatsbyJS Bot committed Sep 19, 2019
1 parent 547ce99 commit e451815
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 5 deletions.
9 changes: 9 additions & 0 deletions packages/gatsby-plugin-offline/src/gatsby-browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ function setPathResources(path, getResourceURLsForPathname) {
exports.onRouteUpdate = ({ location, getResourceURLsForPathname }) => {
const pathname = location.pathname.replace(__BASE_PATH__, ``)
setPathResources(pathname, getResourceURLsForPathname)

if (
`serviceWorker` in navigator &&
navigator.serviceWorker.controller !== null
) {
navigator.serviceWorker.controller.postMessage({
gatsbyApi: `enableOfflineShell`,
})
}
}

exports.onPostPrefetchPathname = ({ pathname, getResourceURLsForPathname }) => {
Expand Down
19 changes: 19 additions & 0 deletions packages/gatsby-plugin-offline/src/gatsby-ssr.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import React from "react"

export const onPreRenderHTML = ({
getHeadComponents,
pathname,
Expand All @@ -20,3 +22,20 @@ export const onPreRenderHTML = ({

replaceHeadComponents(filteredHeadComponents)
}

export const onRenderBody = ({ pathname, setHeadComponents }) => {
if (pathname !== `/offline-plugin-app-shell-fallback/`) {
return
}

setHeadComponents([
<noscript key="disable-offline-shell">
<link
rel="preload"
as="fetch"
href="/.gatsby-plugin-offline:disableOfflineShell"
/>
<meta httpEquiv="refresh" content="0;url=" />
</noscript>,
])
}
33 changes: 28 additions & 5 deletions packages/gatsby-plugin-offline/src/sw-append.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@
importScripts(`idb-keyval-iife.min.js`)

const { NavigationRoute } = workbox.routing
let offlineShellEnabled = true

const navigationRoute = new NavigationRoute(async ({ event }) => {
if (!offlineShellEnabled) {
return await fetch(event.request)
}

let { pathname } = new URL(event.request.url)
pathname = pathname.replace(new RegExp(`^%pathPrefix%`), ``)

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

workbox.routing.registerRoute(navigationRoute)

const messageApi = {
setPathResources(event, { path, resources }) {
// prefer standard object syntax to support more browsers
const MessageAPI = {
setPathResources: (event, { path, resources }) => {
event.waitUntil(idbKeyval.set(`resources:${path}`, resources))
},

clearPathResources(event) {
clearPathResources: event => {
event.waitUntil(idbKeyval.clear())
},

enableOfflineShell: () => {
offlineShellEnabled = true
},

disableOfflineShell: () => {
offlineShellEnabled = false
},
}

self.addEventListener(`message`, event => {
const { gatsbyApi } = event.data
if (gatsbyApi) messageApi[gatsbyApi](event, event.data)
const { gatsbyApi: api } = event.data
if (api) MessageAPI[api](event, event.data)
})

workbox.routing.registerRoute(/\/.gatsby-plugin-offline:.+/, ({ event }) => {
const { pathname } = new URL(event.request.url)

const api = pathname.match(/:(.+)/)[1]
MessageAPI[api]()

return new Response()
})

0 comments on commit e451815

Please sign in to comment.