In this tutorial, we assume you already have a basic understanding of the Flask framework and that you can build an app as simple as the following :
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run()
where the index.html looks like :
<!-- index.html -->
<html>
<body>
<h1>This is a very long name for a simple PWA</h1>
</body>
</html>
To turn this Flask app into a PWA, you can follow these steps :
- Add a
manifest.json
file to the root of your project, which defines the properties of your PWA:
{
"name": "My PWA",
"short_name": "PWA",
"start_url": "/",
"scope": "/",
"display": "standalone",
"theme_color": "#317EFB",
"background_color": "#317EFB",
"icons": [
{
"src": "/static/icons/icon_144x144.png",
"sizes": "144x144",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "/static/icons/icon_192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "/static/icons/icon_512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
]
}
Be careful of not omitting any manifest field that follows the PWA development best practice and add all the required icons to the static/icons/ folder.
Register it in your Flask app :
# app.py
...
@app.route('/manifest.json')
def serve_manifest():
return send_file('manifest.json', mimetype='application/manifest+json')
2. Add a service worker
to your project, which allows your PWA to work offline and improve performance. To do this, create a file called sw.js
in located at the root of your project :
//sw.js
self.addEventListener('install', function(event) {
console.log('[Service Worker] Installing Service Worker ...', event);
});
self.addEventListener('activate', function(event) {
console.log('[Service Worker] Activating Service Worker ...', event);
});
self.addEventListener('fetch', function(event) {
console.log('[Service Worker] Fetching something ...', event);
});
and register it in your Flask app :
# app.py
...
@app.route('/sw.js')
def serve_sw():
return send_file('sw.js', mimetype='application/javascript')
3. Add the manifest.json
file and the service worker
to your HTML template as well as the minimal requirements for responsive design and icons in your header :
<!-- index.html -->
<head>
<meta name="theme-color" content="#317EFB"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="{{url_for('static', filename='icons/icon_144x144.png')}}" type="image/png">
<link rel="icon" href="{{url_for('static', filename='icons/icon_192x192.png')}}" type="image/png">
<link rel="icon" href="{{url_for('static', filename='icons/icon_512x512.png')}}" type="image/png">
<link rel="apple-touch-icon" href="{{url_for('static', filename='icons/icon_144x144.png')}}" type="image/png">
<link rel="apple-touch-icon" href="{{url_for('static', filename='icons/icon_192x192.png')}}" type="image/png">
<link rel="apple-touch-icon" href="{{url_for('static', filename='icons/icon_512x512.png')}}" type="image/png">
<link rel="manifest" href="/manifest.json">
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register("/sw.js").then(function(registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}, function(err) {
console.log('ServiceWorker registration failed: ', err);
});
});
}
</script>
</head>
4. Test your PWA by running the Flask app and visiting it in a web browser that supports service workers (such as Google Chrome).
5. Access the website from your device and add it to your home screen. You should now have an icon stored in static/icons/ displayed on your device such as :
6. Clicking this app should render the web app as a native app seamlessly (without any url searchbox as a header) :
If you carefully followed the step I described, using the great Lighthouse App from Google, the audit of your Flask PWA should be a success :
That’s all ! You can now display your Flask applications as Progressive Web apps ! I hope you have learned something today and as usual, all the code is available on my github.
Thanks for reading !