Introduction:
I am developing a webapp using the SvelteKit
framework,
I implemented some basic functionality for making accessible even to mobile devices:
So basically I think I have a ready-to-use website
that can easily be usable on mobile devices.
What I want?:
I want that my website to be downloaded as a apk
to make it working also Offline
and hopefully even be publishable on Google Play Store.
My research:
I did some research before asking,
and I found that we can use a concept called PWA
, a acronym for Progressive Web App.
What is the problem?
It's seems easy, but in reality,
It turn out to be very difficult to implement using framework like 'SvelteKit'
Question?:
Is there any simpler way than these before,
to transform a vite sveltekit webapp to a PWA?
I want also to be simple because I want to
focus more on Business/App logic than implementing PWA logic.
What things, the answer should solve?
What I tried, if interest you but these are failed tryies (you can skip this part):
- First and obvious way, code it by yourself from scratch everytime
but 'SvelteKit' has a lot of scenarios that you need to consider since it leverage 'SSR'.
But as you know is time consuming
to focus on making PWA functionality to work
than using that time to make the app even more better or solving some bugs.
- use a PWA library called Workbox create by Google itself,
here their github https://github.com/GoogleChrome/workbox
and even with this library this process is still difficult, especially using SvelteKit framework.
- using a PWA library, based on top of Workbox, called Vite PWA.
The landing page of this library use as marketing phrase "Zero-config and framework-agnostic PWA Plugin for Vite".
Theoretically, it should be true, At the start seems to do his job,
but in my experience it contains some bugs that you definitely doesn't want to deal with...
for example one of them is this: https://github.com/vite-pwa/vite-plugin-pwa/issues/40
It creates bugs that don't make sense, basically making your app over-complex for nothing.
- and much more...
all of these are failed examples,
I hope you will find a better way than these
here is the easiest way to make a PWA from SvelteKit, that should work always, without any library:
service-worker
you can't use another name, it's important to use specifically this
/src
folderDON'T insert it inside '/lib' or '/routes', but inside their parent '/src'
/service-worker
, create a new file called index.ts
index.js
if you don't like using Typescript)below you can see a image, I created for you, to make you understand visually the structure (semplified version):
/// <reference types="@sveltejs/kit" />
// @ts-nocheck
import { build, files, version } from '$service-worker';
// Create a unique cache name for this deployment
const CACHE = `cache-${version}`;
const ASSETS = [
...build, // the app itself
...files // everything in `static`
];
self.addEventListener('install', (event) => {
// Create a new cache and add all files to it
async function addFilesToCache() {
const cache = await caches.open(CACHE);
await cache.addAll(ASSETS);
}
event.waitUntil(addFilesToCache());
});
self.addEventListener('activate', (event) => {
// Remove previous cached data from disk
async function deleteOldCaches() {
for (const key of await caches.keys()) {
if (key !== CACHE) await caches.delete(key);
}
}
event.waitUntil(deleteOldCaches());
});
self.addEventListener('fetch', (event) => {
// ignore POST requests etc
if (event.request.method !== 'GET') return;
async function respond() {
const url = new URL(event.request.url);
const cache = await caches.open(CACHE);
// `build`/`files` can always be served from the cache
if (ASSETS.includes(url.pathname)) {
return cache.match(url.pathname);
}
// for everything else, try the network first, but
// fall back to the cache if we're offline
try {
const response = await fetch(event.request);
if (response.status === 200) {
cache.put(event.request, response.clone());
}
return response;
} catch {
return cache.match(event.request);
}
}
event.respondWith(respond());
});
like I said you don't have to understand these lines of code, just copy and paste and they should work in most of cases (it's written by SvelteKit maintainers themselves)
for more details about this code...
I got this code here: https://kit.svelte.dev/docs/service-workers#inside-the-service-worker
all the files inserted in this folder are treated by default as service-workers...
is cool, right?
service workers aren't used only for PWA,
but also for much more...
for example for making your app work even in background,
but thats is definitely another topic.
manifest.json
file, inside your static
folder (you can't use another folder unfortunately)
icons
(with at least one image)name
"display": "standalone"
to make the webapp feel like an android app by eliminating the browser bar.
{
"name": "APP NAME",
"description": "YOUR DESCRIPTION",
"display": "standalone",
"start_url": "/",
"icons": [
{
"src": "icons/myIcon512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
]
}
if you want a more detailed
manifest.json
see this doc: https://developer.mozilla.org/en-US/docs/Web/Manifest
app.html
<link rel="manifest" href="/manifest.json">
as you see this way is easy/fast/efficient,
and it takes less than one minute!
and the most important thing: no need for external libraries
have a nice coding day!