This guide will walk you through the process of adding Progressive Web App (PWA) features to your Flask application. By the end, your app will have a manifest file, a service worker for offline functionality, and be installable on supported devices.
The manifest.json file provides metadata about your web application. It tells the browser how your app should behave when installed on the user's device.
Create a new file named manifest.json in your static folder.
Add the following content to the file:
{
"name": "Your Collection App",
"short_name": "Collection",
"description": "An app to manage your collection of items",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#007bff",
"icons": [
{
"src": "/static/images/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/static/images/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"screenshots": [
{
"src": "/static/images/screenshot-wide.png",
"sizes": "1280x800",
"type": "image/png",
"form_factor": "wide"
},
{
"src": "/static/images/screenshot-narrow.png",
"sizes": "750x1334",
"type": "image/png",
"form_factor": "narrow"
}
]
}
3. Replace "Your Collection App" with the name of your application.
4. Similarly, write a suitable description and short_name that matches what your application does.
5. Create two PNG icons (192x192 and 512x512 pixels) and place them in your static/images folder.
6. Take two PNG screenshots of your app.
You can use DevTools to easily set custom resolutions.
E.g. Adjust to 1280x800 for Desktop view, and then 750x1334 for Mobile view.
There is a 'Capture screenshot' tool built into DevTools as well (shown).
Rename them as shown above and place in the static/images folder.
Check the final size of your images and update the resolutions to match in manifest.json.
Add the following line inside the <head> tag of your base.html template:
<link rel="manifest" href="{{ url_for('static', filename='manifest.json') }}">
The service worker caches important files and serves them from the cache when offline.
Create a new file named service-worker.js in your static folder.
Add the following content to the file:
const CACHE_NAME = 'collection-app-v1';
const urlsToCache = [
'/',
'https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css',
'https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js'
'/static/css/custom.css',
'/static/images/icon-192x192.png',
'/static/images/icon-512x512.png'
];
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME)
.then((cache) => cache.addAll(urlsToCache))
);
});
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request)
.then((response) => {
if (response) {
return response;
}
return fetch(event.request);
})
);
});
Add the following script to your base.html template, just before the closing </body> tag:
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register("{{ url_for('static', filename='service-worker.js') }}")
.then((reg) => console.log('Service worker registered.', reg))
.catch((err) => console.log('Service worker registration failed:', err));
});
}
</script>
Run your Flask application.
Open Chrome DevTools (F12 or Ctrl+Shift+I).
Go to the "Application" tab, you should see:
Manifest: Check if your manifest is loaded correctly.
Service Workers: Verify that your service worker is registered and active.
In Chrome, you should see an install icon in the address bar to "Install app".
Click it to install your PWA as a standalone application.
Click the install button and it should pop out like its own app in Windows. It won't be possible to test it on mobile unfortunately as PWA's must be served from either localhost or https - which would mean we need to host it online and get an SSL certifate.