// cache our offline page
// revision should be updated manually here
workbox.precaching.precacheAndRoute([{
"url": "/offline/",
"revision": "d3ab5addsdef6bsse1864b1b4719e5e54ff21"
}]);
/*
| --------------------------------------------------------------------------
| Caching of the product pages
| --------------------------------------------------------------------------
*/
const productsNetworkFirstHandler = workbox.strategies.networkFirst({
cacheName: 'products',
plugins: [
new workbox.expiration.Plugin({
maxEntries: 30,
maxAgeSeconds: 2 * 30 * 24 * 60 * 60,
}),
new workbox.cacheableResponse.Plugin({
statuses: [200]
}),
]
});
workbox.routing.registerRoute(/\/produit\//, (args) => {
return productsNetworkFirstHandler.handle(args).then((response) => (!response) ? caches.match('/offline/') : response);
});
/**
* List the caches names
* @returns {promise} cache names
*/
async function listCaches(){
const cacheNames = await caches.keys();
if(!cacheNames){
throw new Error('no caches');
}
return cacheNames;
}
/**
*
* Get the requests saved ina given cache
* @param {string} cacheName
* @returns {promise} keylist
*/
async function getCachedRequest(cacheName){
const requests = await caches.open(cacheName);
return await requests.keys()
}
(async () => {
const caches = await listCaches();
for( const cache of caches ){
const requests = await getCachedRequest(cache)
// now you have all the requests feel free to inject them on the page etc...
console.log(requests)
}
})().catch(console.log)
module.exports = {
globDirectory: './',
globPatterns: [
'css/app.css',
'js/libs/jquery.js',
'js/libs/turbolinks.js',
'js/app.bundle.js',
'img/header-logo-white.png',
'img/header-logo-small-black.png'
],
swSrc: './serviceworker-dev.js',
swDest: './serviceworker.js'
};
serviceworker-dev :
importScripts("https://storage.googleapis.com/workbox-cdn/releases/3.0.1/workbox-sw.js");
workbox.skipWaiting();
workbox.clientsClaim();
workbox.core.setLogLevel(workbox.core.LOG_LEVELS.debug);
/**
* The workboxSW.precacheAndRoute() method efficiently caches and responds to
* requests for URLs in the manifest.
* See https://goo.gl/S9QRab
*/
workbox.precaching.precacheAndRoute([]);
// cache our offline page
// revision should be updated manually here
workbox.precaching.precacheAndRoute([{
"url": "/offline/",
"revision": "d3ab5addsdef6bsse1864b1b4719e5e54ff21"
}]);
And run npx workbox injectManifest workbox-config.js
Add a class to the html
main tag when offline
const $html = document.querySelector('html');
function addOfflineElements(){
$html.classList.add('offline');
}
function removeOfflineElements(){
$html.classList.remove('offline');
}
if( ! navigator.onLine ) addOfflineElements();
if( navigator.onLine ) removeOfflineElements();
addEventListener("offline", addOfflineElements );
addEventListener("online", removeOfflineElements );
The CSS :
Change the style of element or hide them when offline
/*
* All elements which should be hidden when offline
*/
.offline form.cart .bouton,
.offline .menu-account,
.offline .menu-cart
{
display: none;
}
// Offline producst management
if ( document.querySelector('.product-category') !== null ){
// we query the cache named products (which contains the products URLs )
getRequestsFromCache('products')
.then( requests => {
const offlineUrls = [];
// we pursh the urls to the array offlineUrls
requests.forEach( r => offlineUrls.push(r.url) );
// we loop through our product list and check if the current URL is in the array
document.querySelectorAll('.product-category a').forEach( a =>{
if( ! offlineUrls.includes(a.href) && a.querySelector('article') !== null) {
// if not offline we add the class not-offline
a.querySelector('article').classList.add('not-offline');
}
});
});
}
.not-offline{
border: solid #0202020d 1px;
opacity:0.2;
}
function injectOfflineBanner(){
let elem = document.createElement('div');
elem.style.cssText = `
position: fixed;
background-color: #6d6d6d;
bottom: 0;
left: 0;
right: 0;
height: 46px;
line-height: 40px;
text-align: center;
color: #FFF;
z-index: 9999999999;
`;
elem.id = "offline-banner";
elem.innerText = "Heads up : You are offline";
document.body.appendChild(elem);
}
function removeOfflineBanner(){
const offlineBanner = document.querySelector("#offline-banner");
if( offlineBanner !== null ) offlineBanner.parentNode.removeChild(offlineBanner);
}
if( ! navigator.onLine ) injectOfflineBanner();
if( navigator.onLine ) removeOfflineBanner();
addEventListener("offline", () => injectOfflineBanner() );
addEventListener("online", () => removeOfflineBanner() );