If you're a Gmail user, but want a native app like experience, you might be using the Create shortcut... feature available in Chrome and Chrome-based browsers, such as Vivaldi. This feature opens a specific URL, such as https://gmail.com/
, in a dedicated browser window and provides a separate icon on the dock (MacOS) or taskbar (Windows). But by default there's no badge counter for unread emails.
Fortunately, it is possible to add a badge by using the experimental Navigator.setAppBadge()
API. This experimental API is available only in Chrome as of this writing. Here I am going to combine the badge API with Violentmonkey, a browser extension that uses the WebExtension APIs.
If you want to use the script, it is available from a GitHub repository in the gmail-badge/dist/index.user.js
file.
Most of the work is performed by a MutationObserver. The API is wrapped by VM.observe
for convenience, and so we only need to provide a DOM element to monitor for mutations and a callback function:
import * as VM from '@violentmonkey/dom';
VM.observe(document.head, () => {
const $el = document.querySelector('title');
// https://github.com/developit/Gmail-unread-count-badge/blob/main/src/content.js
let m = String($el.innerText).match(/Inbox(?: \((\d+)\))? -/);
if (m) navigator.setAppBadge(m[1] | 0 || null);
});
In the preceding code, we do the following:
- Observe the
<head>
DOM element for any changes. - React to a change by querying the
<title>
DOM element, extracting the unread message count, and callingnavigator.setAppBadge
to set the badge number.
By using a MutationObserver, we ensure that whenever Google updates the unread message count in the page title, we can update our unread messages icon badge.
For reference, VM.observe
wraps the MutationObserver.observe
method in the following way:
export function observe(
node: Node,
callback: (
mutations: MutationRecord[],
observer: MutationObserver
) => boolean | void,
options?: MutationObserverInit
): () => void {
const observer = new MutationObserver((mutations, ob) => {
const result = callback(mutations, ob);
if (result) disconnect();
});
observer.observe(
node,
Object.assign(
{
childList: true,
subtree: true,
},
options
)
);
const disconnect = () => observer.disconnect();
return disconnect;
}
The source is available on GitHub and the userscript lives at: gmail-badge/dist/index.user.js
.
Top comments (0)