Is there a way to detect if the browser has a mailto protocol handler set?
Asked Answered
B

1

3

I have a site that dynamically builds a mailto url which it then opens in a new tab/window, using window.open().

window.open("mailto:" + encodeURIComponent(r["to"]));

I'm testing in Chrome at this stage, so other browsers may act differently.

If Chrome has a mailto protocol handler set up (e.g. GMail), then it works as expected.

If Chrome does not have a mailto protocol handler set up, it just opens a tab with the mailto url and nothing else.

That's not the worst result, but it would be nice if there was a way of knowing in advance, so that the user could be in some way guided to setting up their browser so that the mailto url worked nicely.

Previously, I was just opening in the same page by setting window.location.href to the url:

windows.location.href = "mailto:" + encodeURIComponent(r["to"]);

This wasn't great because if there was no protocol handler set, nothing happened. I also would consider this as an option, IF I can at least detect the situation, but wasn't able to find any indication of that either. I guess one option would be to set a timer which if it reached execution could alert the user?

Anyone else already solved this? Seems like a pretty common requirement.

Thanks

Burkle answered 13/11, 2021 at 4:59 Comment(2)
This is an anti-pattern, so no, it has not been generally solved. There is a clear delineation of responsibility here, and it's not the job of any/every website to coach the user through the setup of their PC. Just serve up well-formed content. The rest is up to the user.Aqueous
@meager I disagree. It's reasonable for software to be responsive to the user's configuration and offer helpful information.Burkle
B
1

Here's what I ended up working with. It doesn't work in all cases, but provides at least some help in recognising unhandled protocols.

It attempts to open the URL in a new window and then after 2s it takes a look to see if it can read the location. If it has opened a third party site (e.g. GMail) this will raise and exception - so we treat this as success.

If no exception occurs, this returns "about:blank" which means we (probably) failed.

function openWin(url) {
  return new Promise((resolve, reject) => {
    const w = window.open(url);
    if (!w) {
      reject();
    }
    setTimeout(function() {
      try {
        const working = w.document.location.href;
      } catch (e) {
        resolve();
        return;
      }
      w.close();
      reject();
    }, 2000);
  });
}

Called with something like this:

openWin('mailto:' + encodeURIComponent(to)).then(() => {
  // handle success
}).catch(() => {
  // handle failure
});

Caveat: This only works for web-based protocol handlers. If for example your mailto is handled by an email app, then this will fail.

In my case, most people would be using web-based email, so it works for most cases. On failure I show a message to the affect of "If your email didn't open, copy the email address here..."

Burkle answered 15/11, 2021 at 0:14 Comment(1)
this is the only way i could gracefully handle mailto links in an iframe silently failing for some users in chrome, it all comes down to how they've configured chrome://settings/handlers and whether they've blocked or allowed these settingsChocolate

© 2022 - 2024 — McMap. All rights reserved.