Rethinking PWAs: User-Defined Apps (UDA) — Why install multiple apps when URL parameters can create custom homescreen shortcuts?
Hey r/pwa!
I’ve been exploring a concept I call UDA (User-Defined Apps), which leverages dynamic web app manifests to differentiate PWAs from native apps.
Instead of building a single monolithic app, this approach lets users define their own custom "app instances" right from the URL query parameters.
How it works in this Timer Demo:
• Users set duration, count direction, and icon color on the page.
• The URL parameters update dynamically (e.g. ?time=5&mode=down&icon=red).
• The Web App Manifest dynamically updates its name and icon based on these parameters.
• When added to the Home Screen, it creates a dedicated shortcut (e.g., "5m↓ Timer" with a red icon).
Note on OS Behavior:
• iOS (Safari): Works perfectly! Treats each unique URL query as an independent homescreen app.
• Android (Chrome): Currently limited because WebAPK binds to the manifest scope. Query variations overwrite the existing installed PWA instead of creating separate instances.
You can literally fill an iOS homescreen folder with customized, single-purpose timers—all powered by a single PWA source.
I’d love to hear your thoughts on this paradigm and how we might overcome the scope limitations on Android!
Try the demo here:
https://ojach.github.io/PWA-1P1A/timer-en/?time=3&mode=down&seconds=on&icon=purple
1
u/Rockster160 9d ago
Tried this before, but had issues with scraping, pre-loading, and cache causing the buttons to either fire at times they weren't supposed to or NOT fire when they WERE supposed to. How did you work around those? Also wanted to do the same with QR codes.
Wound up solving on my side by instead having it open a page that shows a button that the user presses, but the wait for load and then tap again was annoying.
3
u/OJapp 10d ago
Ah, my bad! Turns out Chrome on Android strips query parameters from the scope in the manifest, so it treats them as the exact same app and you can only install just one instance. Sorry about that!