PWA: set manifest.json name & icon dynamically; client-side. Jabbadabbadoo!

This is my 1st write up on dev.to site. Source code included as link. I use VueJS, but you can use vanilla JS too.

manifest.json

PWA app needs manifest.json to be installable. We usually have index.html with the link to the manifest.json fi…


This content originally appeared on DEV Community and was authored by Pavel Kříž

This is my 1st write up on dev.to site. Source code included as link. I use VueJS, but you can use vanilla JS too.

manifest.json

PWA app needs manifest.json to be installable. We usually have index.html with the link to the manifest.json file, the separate one, where all items are defined. This file is static, the only way to change it is to edit it's source code (as you are developer, NOT user). Suppose we serve static files, not dynamically created by node.js or similar server side technology.

Today I will show you a practical example how to change some manifest's items dynamically on client side, i.e. as user.

note

I need to say my work is not my invention, it is based on excellent work, ideas and researches of other developers.
Special thanks to alshakero, his post How to Setup Your Web App Manifest Dynamically Using Javascript was very helpful.

idea

We need only three steps to allow user to dynamically set some manifest.json items.

  • create a form outside the index.html to set items (not mandatory)
  • read manifest.json items as parameters from url (aka index.html?name=myApp&icon=icon_1)
  • modify object represented manifest.json and inject it into index.html file

Sounds easy, right?

step 1: the form

I write PWA as SPA (single page application) with all content inside index.html using template tags. Navigating via menu or url is maintained by the router and serves corresponding components (template + data) inside already loaded index.html.

For this step - creating the user form - we write another file named config.html. This file is separate and will NOT be included as asset in our PWA app (will NOT be cached via service worker).

This page - config.html - has form and submit button. On click event JS code assign user's input into variables and append it to index.html url as parameters and redirect page to index.html

Important part of config.js file:

var url = "https://pwa-dynamic-manifest.pablo74.repl.co/index.html?";
var params = "";
var fullUrl = "";

if (this.name){
  params += "name=" + this.name;
};
if (this.short_name){
  params += "&short_name=" + this.short_name;
};
if (this.bgColor){
  params += "&bg=" + this.bgColor;
};
if (this.isActive){
  params += "&icon=" + this.isActive + ".png";
}

fullUrl = url + params;
window.location.replace(fullUrl);

See my source code of config.html and config.js

step 2: read parameters from url

We add link to app.js file inside index.html, it contains prefilled object as manifest.json data and code to read parameters and modify object.

Prefilled object (implicit values):

var manifestJSON = 
{
  "name": "info-()",
  "short_name": "info-()",
  "scope": "https://pwa-dynamic-manifest.pablo74.repl.co/",
  "start_url": "https://pwa-dynamic-manifest.pablo74.repl.co/index.html",
  "display": "standalone",
  "icons": [
    {
      "src": "https://pwa-dynamic-manifest.pablo74.repl.co/img/icon_192_192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "https://pwa-dynamic-manifest.pablo74.repl.co/img/icon_512_512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "background_color": "black",
  "theme_color": "#027be3"
};

Pay attention to scope and start_url property; we usually use something like "scope": "/" and "start_url": "/" but it doesn't work for me; so I have to change it to full url. This is the trick I have not seen elsewhere.

Now is time to show how to read parameters from url:

var urlParams = new URLSearchParams(window.location.search);
var name = urlParams.get('name');
var short_name = urlParams.get('short_name');
var bg = urlParams.get('bg');
var icon = urlParams.get('icon');

step 3: modify object represented manifest.json and inject it into index.html file

There is a custom element in index.html for manifest.json file:

<link rel="manifest" id="my-manifest-placeholder">

You can see there is NOT href attribute, so this link is not functional yet.

Having variables from step 2 we can now modify object and inject it into index.html

if (name){
  manifestJSON.name = name;
};

if (short_name){
  manifestJSON.short_name = short_name;
};

if (bg) {
  manifestJSON.background_color = bg;
};

if (icon){
  manifestJSON.icons[0].src = "https://pwa-dynamic-manifest.pablo74.repl.co/img/" + icon;
}

const stringManifest = JSON.stringify(manifestJSON);
const blob = new Blob([stringManifest], {type: 'application/json'});
const manifestURL = URL.createObjectURL(blob);
document.querySelector('#my-manifest-placeholder').setAttribute('href', manifestURL);

You may think: "Hey, stop, where are the icons?". Right question. All icons are already included as assets in img folder; i.e. this way we set apps icon from our set of icons only, not from external files.

Does it really work?

Yes, I tested it on two Android devices: mobile phone with Android 7 and tablet with Android 10. I am able to install even three apps with different name and icon on the same device from the same code base.

Full source code

Because I use work of other developers, it is fair to show and spread all source code. You can find it on replit.com (repl.it previously): pwa-dynamic-manifest
If you have an account you can simply fork this repl and modify it as needed.

Important note

Use first config.html to load form, otherwise (loading index.html directly) you will not be able to modify manifest.json (unless you use url parameters directly).

Improvements...?

This is a functional proof of concept, you can modify and enhance it as you like :-)


This content originally appeared on DEV Community and was authored by Pavel Kříž


Print Share Comment Cite Upload Translate Updates
APA

Pavel Kříž | Sciencx (2021-08-05T22:08:24+00:00) PWA: set manifest.json name & icon dynamically; client-side. Jabbadabbadoo!. Retrieved from https://www.scien.cx/2021/08/05/pwa-set-manifest-json-name-icon-dynamically-client-side-jabbadabbadoo/

MLA
" » PWA: set manifest.json name & icon dynamically; client-side. Jabbadabbadoo!." Pavel Kříž | Sciencx - Thursday August 5, 2021, https://www.scien.cx/2021/08/05/pwa-set-manifest-json-name-icon-dynamically-client-side-jabbadabbadoo/
HARVARD
Pavel Kříž | Sciencx Thursday August 5, 2021 » PWA: set manifest.json name & icon dynamically; client-side. Jabbadabbadoo!., viewed ,<https://www.scien.cx/2021/08/05/pwa-set-manifest-json-name-icon-dynamically-client-side-jabbadabbadoo/>
VANCOUVER
Pavel Kříž | Sciencx - » PWA: set manifest.json name & icon dynamically; client-side. Jabbadabbadoo!. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/08/05/pwa-set-manifest-json-name-icon-dynamically-client-side-jabbadabbadoo/
CHICAGO
" » PWA: set manifest.json name & icon dynamically; client-side. Jabbadabbadoo!." Pavel Kříž | Sciencx - Accessed . https://www.scien.cx/2021/08/05/pwa-set-manifest-json-name-icon-dynamically-client-side-jabbadabbadoo/
IEEE
" » PWA: set manifest.json name & icon dynamically; client-side. Jabbadabbadoo!." Pavel Kříž | Sciencx [Online]. Available: https://www.scien.cx/2021/08/05/pwa-set-manifest-json-name-icon-dynamically-client-side-jabbadabbadoo/. [Accessed: ]
rf:citation
» PWA: set manifest.json name & icon dynamically; client-side. Jabbadabbadoo! | Pavel Kříž | Sciencx | https://www.scien.cx/2021/08/05/pwa-set-manifest-json-name-icon-dynamically-client-side-jabbadabbadoo/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.