Skip to content

Instantly share code, notes, and snippets.

@edsonmsantos
Last active March 2, 2023 13:27
Show Gist options
  • Save edsonmsantos/b934cd363009c2dedd4a973be0d2fee0 to your computer and use it in GitHub Desktop.
Save edsonmsantos/b934cd363009c2dedd4a973be0d2fee0 to your computer and use it in GitHub Desktop.
Arquivos necessários para PWA

Preparar site como PWA

Adicione a seguinte meta a sua página HTML:

<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="shortcut icon" type="image/png" href="/android-chrome-512x512.png">
<link rel="manifest" href="/site.webmanifest">
<meta name="theme-color" content="rgb(220,220,225)">
<meta content='yes' name='apple-mobile-web-app-capable' />
<meta content='yes' name='mobile-web-app-capable' />

Adicione o seguinte script no final da página HTML

<script>
    if ('serviceWorker' in navigator) {
        if (navigator.serviceWorker.controller) {
            console.log('[PWA] active service worker found, no need to register')
        } else {
            navigator.serviceWorker.register('/sw.js', {
                scope: '/'
            }).then(function (registration) {
                console.log('ServiceWorker registration successful with scope: ', registration.scope);
                registration.pushManager.getSubscription();
            }).catch(function (err) {
                console.log('ServiceWorker registration failed: ', err);
            });
        }
    } else {
        console.log('ServiceWorker not supported');
    }

    if (!("Notification" in window)) {
        console.log("This browser does not support desktop notification");
    } else if (Notification.permission === "granted") {
        console.log('granted');
    } else if (Notification.permission !== "denied") {
        Notification.requestPermission().then((permission) => {
            if (permission === "granted") {
                console.log('granted');
            }
        });
    }
</script>

Crie o seguinte arquivo de manifesto (/site.manifest):

{
	"name": "",
	"short_name": "",
	"icons": [{
		"src": "/android-chrome-192x192.png",
		"sizes": "192x192",
		"type": "image/png"
	}, {
		"src": "/android-chrome-512x512.png",
		"sizes": "512x512",
		"type": "image/png"
	}],
	"theme_color": "#ffffff",
	"background_color": "#ffffff",
	"display": "standalone",
  "start_url": "/",
}

Crie o seguinte service worker (/sw.js):

const CACHE = "offline-page";
const offlineFallbackPage = "/offline.html";
self.addEventListener("install", function (event) {
    event.waitUntil(
        caches.open(CACHE).then(function (cache) {
            return cache.add(offlineFallbackPage);
        })
    );
});

// If any fetch fails, it will look for the request in the cache and serve it from there first
self.addEventListener("fetch", function (event) {
    if (event.request.method !== "GET") return;

    event.respondWith(
        fetch(event.request)
            .then(function (response) {
                // If request was success, add or update it in the cache
                event.waitUntil(updateCache(event.request, response.clone()));

                return response;
            })
            .catch(function (error) {
                return fromCache(event.request);
            })
    );
});

function fromCache(request) {
    // Check to see if you have it in the cache
    // Return response
    // If not in the cache, then return the offline page
    return caches.open(CACHE).then(function (cache) {
        return cache.match(request).then(function (matching) {
            if (!matching || matching.status === 404) {
                // The following validates that the request was for a navigation to a new document
                if (request.destination !== "document" || request.mode !== "navigate") {
                    return Promise.reject("no-match");
                }

                return cache.match(offlineFallbackPage);
            }

            return matching;
        });
    });
}

function updateCache(request, response) {
    return caches.open(CACHE).then(function (cache) {
        return cache.put(request, response);
    });
}

self.addEventListener('message', (event) => {
    if (event.data && event.data.type === 'SKIP_WAITING') {
        self.skipWaiting();
    }
});


self.addEventListener('push', function(e) {
    console.log('PUSH -> ', e.data.text());
    self.registration.showNotification(
        'Meu App Web',
        {
            body: e.data.text(),
            icon: '/favicon-32x32.png',
        }
    );
});

Por fim crie uma página para ser disponibilizada quando estiver offline com o nome /offline.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment