README.md
| @@ -1 +1,5 @@ | |||
| 1 | - | # Service Worker - Offline Page | |
| 1 | + | # Service Worker - Offline Page | |
| 2 | + | ||
| 3 | + | When the end-user goes offline, it is possible to cache a page to their device to show a custom offline page. Examples of this would be sites such as YouTube and X. | |
| 4 | + | ||
| 5 | + | Just use the JavaScript file below, make sure it's at the root of the domain in order for the web browser to pick it up. The HTML file below is an example of an offline page. I would recommend building your own custom offline page to tailor it for your website or web application. | |
gistfile1.txt 重命名為 offline.html
檔案名稱與重新命名前相同
README.md(檔案已創建)
| @@ -0,0 +1 @@ | |||
| 1 | + | # Service Worker - Offline Page | |
gistfile1.txt(檔案已創建)
| @@ -0,0 +1,4 @@ | |||
| 1 | + | <!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="description" content="Astro description"><meta name="viewport" content="width=device-width"><link rel="icon" type="image/svg+xml" href="/favicon.svg"><meta name="generator" content="Astro v4.0.5"><title>Welcome to Astro.</title><style>:root{--accent: 136, 58, 234;--accent-light: 224, 204, 250;--accent-dark: 49, 10, 101;--accent-gradient: linear-gradient( 45deg, rgb(var(--accent)), rgb(var(--accent-light)) 30%, white 60% )}html{font-family:system-ui,sans-serif;background:#13151a;background-size:224px}code{font-family:Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace} | |
| 2 | + | main[data-astro-cid-orgni7iu]{margin:auto;padding:1rem;width:800px;max-width:calc(100% - 2rem);color:#fff;font-size:20px;line-height:1.6}svg[data-astro-cid-orgni7iu]{fill:#fff}.astro-a[data-astro-cid-orgni7iu]{position:absolute;top:-32px;left:50%;transform:translate(-50%);width:220px;height:auto;z-index:-1}h1[data-astro-cid-orgni7iu]{font-size:4rem;font-weight:700;line-height:1;text-align:center;margin-bottom:1em}.text-gradient[data-astro-cid-orgni7iu]{background-image:var(--accent-gradient);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-size:400%;background-position:0%}.error[data-astro-cid-orgni7iu]{margin-bottom:2rem;border:1px solid rgba(var(--accent-light),25%);background:linear-gradient(#650a0aa8,#650a0a54);padding:1.5rem;border-radius:8px;align-items:center;display:flex;gap:12px}.error[data-astro-cid-orgni7iu] code[data-astro-cid-orgni7iu]{font-size:.8em;font-weight:700;background:rgba(var(--accent-light),12%);color:rgb(var(--accent-light));border-radius:4px;padding:.3em .4em}.error[data-astro-cid-orgni7iu] strong[data-astro-cid-orgni7iu]{color:rgb(var(--accent-light))}.instructions[data-astro-cid-orgni7iu]{margin-bottom:2rem;border:1px solid rgba(var(--accent-light),25%);background:linear-gradient(rgba(var(--accent-dark),66%),rgba(var(--accent-dark),33%));padding:1.5rem;border-radius:8px}.instructions[data-astro-cid-orgni7iu] code[data-astro-cid-orgni7iu]{font-size:.8em;font-weight:700;background:rgba(var(--accent-light),12%);color:rgb(var(--accent-light));border-radius:4px;padding:.3em .4em}.instructions[data-astro-cid-orgni7iu] strong[data-astro-cid-orgni7iu]{color:rgb(var(--accent-light))}.link-card-grid[data-astro-cid-orgni7iu]{display:grid;grid-template-columns:repeat(auto-fit,minmax(24ch,1fr));gap:2rem;padding:0} | |
| 3 | + | </style><script type="module">"serviceWorker"in navigator&&navigator.serviceWorker.register("service-worker.js"); | |
| 4 | + | </script></head> <body> <main data-astro-cid-orgni7iu> <p class="error" data-astro-cid-orgni7iu><svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 512 512" data-astro-cid-orgni7iu><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm0-384c13.3 0 24 10.7 24 24V264c0 13.3-10.7 24-24 24s-24-10.7-24-24V152c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z" data-astro-cid-orgni7iu></path></svg> You're offline, check your internet connection and try again.</p> </main> </body></html> | |
service-worker.js(檔案已創建)
| @@ -0,0 +1,38 @@ | |||
| 1 | + | 'use strict'; | |
| 2 | + | ||
| 3 | + | var cacheVersion = 1; | |
| 4 | + | var currentCache = { | |
| 5 | + | offline: 'offline-cache' + cacheVersion | |
| 6 | + | }; | |
| 7 | + | const offlineUrl = 'offline.html'; | |
| 8 | + | ||
| 9 | + | this.addEventListener('install', event => { | |
| 10 | + | event.waitUntil( | |
| 11 | + | caches.open(currentCache.offline).then(function (cache) { | |
| 12 | + | return cache.addAll([ | |
| 13 | + | offlineUrl | |
| 14 | + | ]); | |
| 15 | + | }) | |
| 16 | + | ); | |
| 17 | + | }); | |
| 18 | + | ||
| 19 | + | this.addEventListener('fetch', event => { | |
| 20 | + | // request.mode = navigate isn't supported in all browsers | |
| 21 | + | // so include a check for Accept: text/html header. | |
| 22 | + | if (event.request.mode === 'navigate' || (event.request.method === 'GET' && event.request.headers.get('accept').includes('text/html'))) { | |
| 23 | + | event.respondWith( | |
| 24 | + | fetch(event.request.url).catch(error => { | |
| 25 | + | // Return the offline page | |
| 26 | + | return caches.match(offlineUrl); | |
| 27 | + | }) | |
| 28 | + | ); | |
| 29 | + | } | |
| 30 | + | else { | |
| 31 | + | // Respond with everything else if we can | |
| 32 | + | event.respondWith(caches.match(event.request) | |
| 33 | + | .then(function (response) { | |
| 34 | + | return response || fetch(event.request); | |
| 35 | + | }) | |
| 36 | + | ); | |
| 37 | + | } | |
| 38 | + | }); | |