Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to open mailto links in new tab for users that have gmail as the default mail handler?

On a web page mailto links open the default e-mail client. Now that Chrome offers the ability to set Gmail as the default e-mail client, some users have the links open in the same window thus taking them away from the page they clicked the link (which they do not like)

I have tried adding target _blank to the links, which works great for gmail users, but will drive Outlook users mad, because a new blank tab will open every time they click a mailto link.

I there a way to detect the default e-mail handler and offer a good experience for both types of users?

like image 327
Martin Henk Avatar asked Jul 20 '12 09:07

Martin Henk


People also ask

How do I open mailto in Gmail?

When you click email links in webpages, you can automatically open them in Gmail instead of your desktop client. Just set up Gmail as your default email program. Clicking email links will open the Gmail compose window in a new tab with a pre-filled To: email address field.

How do I change my mailto link default email program?

Go to Settings > Privacy & Security, scroll down to Applications, and under Content Type look for the mailto option. The dropdown menu next to it is where you can specify which email program you want to use. It could be Gmail, Yahoo! Mail, or any other desktop email program such as Thunderbird or Microsoft Outlook.


2 Answers

Okay, so I was able to get this working in Chrome on Mac. Your mileage may vary. Also, this is pretty hacky IMO, so it may not be worth it. Honestly this should exist as a setting within Chrome, and the behavior should be delegated to the website. E.g. Chrome should have an option: "[x] Always open mailto links in separate tab"

That being said, here's how you do it.

First construct your links like so:

<a href="#" data-mailto="[email protected]">Mail Somebody</a> 

Then set a click handler for those.

$('a[data-mailto]').click(function(){   var link = 'mailto.html#mailto:' + $(this).data('mailto');   window.open(link, 'Mailer');   return false; }); 

There is an optional options argument to window.open that you can tweak. In fact I would almost recommend it, to see if you can get the generated window to be as unnoticable as possible. https://developer.mozilla.org/en/DOM/window.open

http://www.w3schools.com/jsref/met_win_open.asp (the MDN doc is exhaustive, while the w3schools doc is almost easier to read)

Next we need to create the mailto.html page. Now you may need to play around with the timeout you see below. You could probably even set this to something really short like 500ms.

<html> <script> function checkMailto(hash){     hash = hash.split('mailto:');     if(hash.length > 1){         return hash[1];     } else {         return false;     } }  var mailto = checkMailto(location.hash);  if(mailto){     location.href = 'mailto:'+mailto;     setTimeout(function(){       window.close();     }, 1000); } </script> </html> 

Results

Mail.app set as my default email reader:

When I click the link, it opens a window for a split second, then composes a blank message. In the browser it goes back to the original page.

Gmail set as mail reader under Settings > Advanced > Privacy > Handlers:

When I click the link, it opens a new tab to Gmail, with the previous page safely in it's own tab.

Note: Once you set Gmail as your email handler, on the OS side (at least on mac), Chrome is set as the system's email handler. So even if you turn off Gmail as the email handler inside Chrome, it is still set on the OS level. So to reset that, I went to Mail > Prefs > General. And set default mail reader back to Mail.

like image 78
Jon Jaques Avatar answered Sep 21 '22 16:09

Jon Jaques


I received a request for implementing this in ownCloud Contacts and though I also think it's a bit hackish, there doesn't seem to be another way of detecting if the mailto handler is set to a webmail address.

This example is implemented without the need for external files.

NOTE: jQuery is needed for this example, but it can probably be rewritten to strict javascript.

To avoid having to use data-mailtoor other tricks, you can instead intercept the handler:

$(window).on('click', function(event) {     if(!$(event.target).is('a[href^="mailto"]')) {         return;     }      // I strip the 'mailto' because I use the same function in other places     mailTo($(event.target).attr('href').substr(7));     // Both are needed to avoid triggering other event handlers     event.stopPropagation();     event.preventDefault(); }); 

Now for the mailTo() function:

var mailTo = function(url) {     var url = 'mailto:' + data.url;     // I have often experienced Firefox errors with protocol handlers     // so better be on the safe side.     try {         var mailer = window.open(url, 'Mailer');     } catch(e) {         console.log('There was an error opening a mail composer.', e);     }     setTimeout(function() {         // This needs to be in a try/catch block because a Security          // error is thrown if the protocols doesn't match         try {             // At least in Firefox the locationis changed to about:blank             if(mailer.location.href === url                      || mailer.location.href.substr(0, 6) === 'about:'             ) {                 mailer.close();             }         } catch(e) {             console.log('There was an error opening a mail composer.', e);         }     }, 500);  } 

I decreased the timeout to 500. Works For Me, lets see what the users say when it's pushed ;)

If you want to avoid opening a new tab/window you can use an iframe. It will require an extra request, but is less annoying if you don't use webmail yourself. This wasn't feasible for ownCloud because per default the Content-Security-Policy is very strict, and injecting "foreign" URLs into an iframe isn't allowed (not tested much):

var mailTo = function(url) {     var url = 'mailto:' + data.url, $if;     try {         $if = $('<iframe />')             .css({width: 0, height: 0, display: 'none'})             .appendTo($('body'))             .attr('src', url);     } catch(e) {         console.log('There was an error opening a mail composer.', e);     }     setTimeout(function() {         try {              if($if.attr('src') !== url                      && $if.attr('src').substr(0, 6) !== 'about:'             ) {                 window.open($if.attr('src'), 'Mailer');             }         } catch(e) {             console.log('There was an error opening a mail composer.', e);         }         $if.remove();     }, 500);  } 
like image 43
tanghus Avatar answered Sep 22 '22 16:09

tanghus