DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for Create a PWA app manifest dynamically
Kevin Basset
Kevin Basset

Posted on • Updated on • Originally published at javascript.plainenglish.io

Create a PWA app manifest dynamically

Every Progressive Web App has an app manifest, a simple JSON file that contains the basic information of your app, i.e. name, icon, description, etc.

If you just want to add PWA functionality to your existing web app, Progressier has everything you need (including dynamic app icons options). But if you want to create your own web app manifest dynamically, please read on.

How it's traditionally done

When building your first PWA, the simplest way to proceed is adding a link to your app manifest directly in the <head> section of your HTML template.

<link rel="manifest" href="/manifest.json">

Host manifest.json anywhere on your site. The resulting JSON file should look like this:

{
   "short_name":"Coronavirus",
   "name":"The Coronavirus App",
   "background_color":"#ffffff",
   "theme_color":"#ffffff",
   "display":"standalone",
   "orientation":"any",
   "start_url":"https://coronavirus.app",
   "scope":"https://coronavirus.app",
   "icons":[
      {"src":"/icon512.png","sizes":"512x512","type":"image/png"},
      {"src":"/icon192.png","sizes":"192x192","type":"image/png"},
      {"src":"/icon196.png","sizes":"196x196","type":"image/png"}
   ]
}
Enter fullscreen mode Exit fullscreen mode

Why you might want to do it differently

While the method above is a perfectly valid way of dealing with web app manifests, there are legitimate cases when a static file won't do and you'll want to generate it dynamically instead:

  • You need completely different icons on desktop and mobile
  • You want to host multiple distinct PWAs on the same domain
  • The PWA should look different for each logged-in user

And there are probably many more valid examples. To generate your app manifest dynamically, you have two options: build it on your server when it's requested by users. Or automatically generate it right in the browser (our preferred method).

Server-side dynamic app manifest generation

Rather than hosting the file as a static file on you site, make the path to /manifest.json an API, which will allow you to generate the content of the JSON file programmatically based on whatever your needs are. Here is an example using Node/Express:

app.get('/manifest.json', async function(req, res){
    //for brevity, we're not including the isDesktop function here
    let iconUrl = isDesktop() ? '/desktop.png' : '/mobile.png';
    let manifest = { 
       name: "App name",
       icons: [{
         src: iconUrl, 
         sizes: "512x512", 
         type:"image/png"
       }]
    }
    res.header('content-type', 'application/json');
    return res.status(200).send(JSON.stringify(manifest));
});
Enter fullscreen mode Exit fullscreen mode

Client-side dynamic app manifest creation

Most people don't know that /manifest.json doesn't have to be an actual file. In fact, it works just fine with a Data URL.

I would even argue that a Data URL is a better way to go about this β€” even if you don't need to generate that particular asset dynamically.

No additional file to download from your server means faster load times and reduced server costs. And since the Data URL will be different every time you modify the content of your web app manifest, you don't have to worry about the browser not updating its content accordingly.

In your client-side code, here is how you can create it:

//for brevity, we're not including the isDesktop function here
let iconUrl = isDesktop() ? '/desktop.png' : '/mobile.png';
let manifest = { 
  name: "App name",
  icons: [{
    src: iconUrl, 
    sizes: "512x512", 
    type:"image/png"
  }]
};
let content = encodeURIComponent(JSON.stringify(manifest));
let url = "data:application/manifest+json,"+content;
let element = document.createElement('link');
element.setAttribute('rel', 'manifest');
element.setAttribute('href', url);
document.querySelector('head').appendChild(element);
Enter fullscreen mode Exit fullscreen mode

At Progressier, we came across quite a few complex use cases of users needing completely different logos on their Android home screen, on their Android splash screen, on their iPhone splash screen and on their Windows/Mac installed PWA, so we've designed our dashboard accordingly.

Progressier dynamic app manifest toggles and inputs

Behind the scenes, we use these user settings to generate their app manifest dynamically with the methods above.

Questions or feedback? Leave a comment below!

Top comments (0)

Classic DEV Post πŸ‘‡

Visualizing Promises and Async/Await 🀯

async await