rishabh3112 / gridsome-plugin-pwa

PWA plugin for gridsome
MIT License
30 stars 18 forks source link

Specify 'maskable' icon for manifest #55

Closed cameronrr closed 2 years ago

cameronrr commented 3 years ago

Is it possible to specify an icon as 'maskable' in the current version?

It looks like the plugin will take the image specified as 'icon' and use that to generate an array of icons, all with purpose 'any'.

Now we will need to have an icon which has purpose 'maskable' or 'maskable any'. See Maskable Icon Audit for more info.

cameronrr commented 3 years ago

If the plugin can handle some more options around the icons in the future that would be great, but for now, something like this might do the trick.

Add a script to package.json in the postbuild hook:

"scripts": {
    "build": "gridsome build",
    "postbuild": "node scripts/postbuild.js",
}

In that file, run some logic to update the generated manifest as needed:

// scripts/postbuild.js
const fs = require('fs')

const fileName = './dist/manifest.json'
const fileContents = fs.readFileSync(fileName)

const manifest = JSON.parse(fileContents)

manifest.icons.forEach((element, index) => {
  element.purpose = 'maskable any'
})

fs.writeFileSync(fileName, JSON.stringify(manifest, null, 4))
rishabh3112 commented 3 years ago

We can add support for this. Shouldn't be difficult to implement. Feel free to send a pull request with the feature, if you like 😃.

cameronrr commented 3 years ago

Great, I shall see if I can get to this shortly.

Noting the following from the link in original post, specifying 'maskable any' is not optimal. Ideally, each icon in the array should only have one purpose, and maskable icons should be specified as unique icons.

While you can specify multiple space-separated purposes like "any maskable", in practice you shouldn't. Using "maskable" icons as "any" icons is suboptimal as the icon is going to be used as-is, resulting in excess padding and making the core icon content smaller. Ideally, icons for the "any" purpose should have transparent regions and no extra padding, like your site's favicons, since the browser isn't going to add that for them.

With this in mind, my thoughts on implementing this:

An alternative approach would be:

Also for consideration:

rishabh3112 commented 3 years ago

With this in mind, my thoughts on implementing this:

icon: '' (required) will continue to generate an array of purpose: 'any' icons
iconMaskable: '' (optional) will generate an array of purpose: 'maskable' icons
The results of both are concatenated into a single icons array for the manifest.json

I prefer this one

Help documentation should also be clearer that icon is required and where the icon file should reside i.e. static folder

Yes, you are right!

Thanks for taking on this issue :)

cameronrr commented 3 years ago

I checked the code closer and I found the option maskableIcon already exists! And it behaves to set purpose: 'maskable any'.

However, as discussed above it is really needed to allow for two different versions of the icon, rather than using the same icon for both purposes in all cases. So will review how to achieve this alongside the existing maskableIcon flag.