Make Phone Numbers Clickable (and Trackable!) Across Mobile Devices With Javascript

January 16, 2014 | Jon Meck

 

Sometimes when dealing with a website, it’s easy to throw on the classic tracking events – PDFs, mailto links, etc… But what if we wanted to track when people clicked on our phone links? In a perfect world, this should be easy. However, phone numbers can be written in many, many different ways and we don’t always have control over the content to add in appropriate phone tags. As if that’s not enough, dealing with different browsers on different devices supremely complicates the matter.

Fear not, through the power of javascript and regular expressions, we can certainly tackle this! This post gets a little long, but I wanted to explain why I made all of the decisions that I did.

If you’re just looking for the code – click here for the javascript.

For this demonstration, I’ll use our office number: 1 (412) 381-5500.

Telephone Numbers on Mobile Websites

There are lots of opinions out there about the best way to write a telephone number on a website. For this post, I’m only going to focus on mobile devices. To summarize the debate quickly, if you’re using a telephone number on a mobile website, the most common way is to wrap phone numbers like so: <a href=”tel:+14123815500″>1 (412) 381-5500</a>. For most mobile browsers, this will allow a user to click directly on your link, which will initiate a phone call to that number. Some desktop sites will use “callto:” which works with Skype and other companies. If you deal with international audiences, the + before the country code is important, though the plus sign is not necessary for in-country calling. This blog post is geared towards North American styled telephone numbers, but feel free to adapt it as needed!

If you can currently format all of the phone numbers like this on your website reliably, then it may be as easy as adding in some javascript to look for those perfectly formatted phone links.

Unfortunately, sometimes we don’t have the option of manually correcting all of our phone numbers. We may have way too many pages to check every one, or we may have dynamic content that we don’t control. Perhaps you have a client that you can support through Google Tag Manager, but that you can’t make any direct changes to content. Or perhaps you share content creation responsibilities and just want a surefire solution to catch mistakes that other people might make.

So moving forward, let’s assume your phone numbers are just plaintext on the page, in a variety of different formats. How do mobile devices currently handle this?

The Major Players

Both Chrome on Android and Safari on Apple devices recognize their own definitions of phone numbers and take actions to make them clickable for your average user. That being said, they go about it different ways, and their definitions of phone numbers don’t necessarily jive with what our definition is. For instance, Apple doesn’t like phone numbers separated by periods, like 1.412.381.5500. Plus – Chrome on an Apple device behaves differently, and there are other mobile browsers that users can download.

Safari on Apple devices will take a phone number on a page and will actually rewrite it onto the page inside of an <a> tag and append “tel:” to the number, like so: <a href=”tel:1 (412) 381-5500″>1 (412) 381-5500</a>. Note that they keep the original formatting of the phone number as it appeared on the page. In addition, this <a> tag will use any existing CSS on the page for <a> tags.

Chrome on Android will make the numbers clickable but does so in a less obvious way. Links are not rewritten, and the phone numbers don’t appear as links. So while phone numbers are automatically made clickable, this doesn’t help out the ability to track these phone numbers. A better solution for us would be to follow the Safari logic and rewrite these links inside of <a> tags.

New Assumptions

Now that we’ve talked about how the major players handle telephone links, we need to revise our assumptions. Even though we started out having only plaintext phone numbers on the page, without our knowledge or consent, we now may have some mix of correctly linked numbers (numbers that Safari recognized) and plaintext numbers (original numbers and numbers in Chrome).

Approach

With this mix of good and bad phone links on the site, we want a way to make all of the links good. I’m using good in this case to mean that we are A) capturing the full range of phone numbers that we define, B) making them all appear as clickable links, and C) making those links trackable. We can do all of this through a combination of javascipt, jQuery, and regular expressions, which then can be put into Google Tag Manager.

Step One

It’s time to define what we think counts as a phone number. I created a regular expression to do so below, but feel free to edit this as needed. It’s a tricky problem to solve, as you want to include the most probable phone numbers as possible, accounting for different symbols and syntaxes. The North American Number Plan has some rules that I’ve incorporated as well. You don’t need to understand regular expressions to get this to work, but if you want a handy guide – check out my blog post from December 2013. Another important thing to note – the code below is written as javascript strings, which we later use to put together the whole regular expression. Therefore, it’s important to double escape characters that you would want to appear in the regular expression.

var countrycodes = "1"
var delimiters = "-|\\.|—|–| "
var phonedef = "\\+?(?:(?:(?:" + countrycodes + ")(?:\\s|" + delimiters + ")?)?\\(?[2-9]\\d{2}\\)?(?:\\s|" + delimiters + ")?[2-9]\\d{2}(?:" + delimiters + ")?[0-9a-z]{4})"

In my definition of a phone number, I’ve said the following:

  • There may or not may not be a + sign at the beginning
  • There may or may not be a country code at the beginning
  • After the country code, there can be a space or any of the delimiters that I’ve defined
  • There must be an area code, which may or may not be surrounded by parentheses
  • The  first digit of the area code must be between 2-9, followed by any 2 numbers
  • After the area code, there can be a space or any of the delimiters that I’ve defined
  • The next number must be between 2-9, followed by any 2 numbers
  • The next character has to be a delimiter that I’ve defined, it cannot be a space.
  • The last block is 4 digits long and can be numbers or letter

Step Two

Now that we have what we count as a phone number, we want to have a way to look for it on the page. We can use jQuery to easily grab the HTML of a given section of your page. It’s important to grab HTML instead of just text, as some of these phone numbers may already be wrapped in <a> tags. If you have a big site, it may be helpful to narrow down which section or sections on your site might contain phone numbers. For instance, on our site, I might grab two divs called “address” and “contact”. You may have a page container that you could use or an article container. To get the HTML of these elements, I can use the following code:

$("#address").html()

It’s helpful to use the smallest section of your site necessary, as we will be rewriting this section later. If you have other automatic tracking in place, you’ll want to run that AFTER this script runs.

Step Three

Find and replace! We can use the replace function in javascript to look through the HTML and replace all phone numbers that we find. This is the really tricky part. If we just look through the code and replace all phone numbers, we’re may run into issues where the phone number appears in the href attribute of an <a> tag as well as in the text of the link. So the function we use has to look for both plaintext numbers and numbers inside of phone links.

To do this, again we’ll look to regular expressions to help us out. You can see that I’ve combined this expression with the definition of a phone number from above. If you can, work through the regular expression to see each of the steps. I’ve started by checking through for any links that already exist using the “callto:” method. While these work well for Skype on a desktop, I’d prefer to use the “tel:” method. I’ve added a rule here saying that the phone number cannot have a number at the beginning or end of it, thus preventing us from finding a phone number in the middle of say, an order number or credit card number. If it finds a plaintext phone number, it will wrap that phone number in an <a> tag, with the link set to “tel:” and a stripped version of the phone number without special characters. If it finds a correctly formatted phone number, it will simply leave it as is.

var spechars = new RegExp("([- \(\)\.:]|\\s|" + delimiters + ")","gi") //Special characters to be removed from the link
var phonereg = new RegExp("((^|[^0-9])(href=[\"']tel:)?((?:" + phonedef + ")[\"'][^>]*?>)?(" + phonedef + ")($|[^0-9]))","gi")

function ReplacePhoneNumbers(oldhtml) {
var newhtml = oldhtml.replace(/href=['"]callto:/gi,'href="tel:')
newhtml = newhtml.replace(phonereg, function ($0, $1, $2, $3, $4, $5, $6) {
    if ($3) return $1;
    else if ($4) return $2+$4+$5+$6;
    else return $2+""+$5+""+$6; }); 
return newhtml;
}

Step Four

Let’s add in the tracking.  You’ll need to have jQuery added to your page already in order for this particularly code to work. The code would be the same basic idea as if you were tracking PDF downloads or MAILTO clicks. Now that our phone numbers are properly encased in <a> tags, we can look for all telephone links on the page, newly created or previously on the page, and add in Google Analytics tracking. I’ve also added in a few lines here that will make our phone numbers more uniform when they go into Google Analytics, removing special characters, and making the numbers consistently 11 characters. When someone clicks on one of these links, we’ll stop the link from firing, send an event to Google Analytics, then after 300 milliseconds, redirect like the page like nothing ever happened.

$("a[href^='tel:']").click(function(event){
     event.preventDefault(); 

     link  = $(this).attr('href');
     tracklink = link.replace("tel:","")
     tracklink = tracklink.replace(spechars,"")
     if(tracklink.length == 10) {tracklink = "1" + tracklink}

     ga('send', 'event', 'Contact', 'Phone', tracklink);
     //_gaq.push(['_trackEvent', 'Contact', 'Phone', tracklink]);

     setTimeout(function() {.
        window.location = link;
     },300);
});

Step Five

We need to decide when we want this to fire. I’ve decided to narrow this down to just after the page is loaded, and only on mobile devices. The code I used is below, but feel free to use your own method of detecting mobile devices.  Again, using jQuery to help with this.

$(document).ready(function(){
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
 // run our other content here
}
})

Implementing the Code – Pure Javascript

We have all the pieces, now let’s put it all together.   The general idea here is to:

  1. Wait until the page is loaded
  2. Check to see that it’s mobile
  3. Grab the HTML from the specific section of the site we want
  4. Run that HTML through our special code
  5. Replace our section with the updated HTML
  6. Add in the tracking
$(document).ready(function(){
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {

var countrycodes = "1"
var delimiters = "-|\\.|—|–| "
var phonedef = "\\+?(?:(?:(?:" + countrycodes + ")(?:\\s|" + delimiters + ")?)?\\(?[2-9]\\d{2}\\)?(?:\\s|" + delimiters + ")?[2-9]\\d{2}(?:" + delimiters + ")?[0-9a-z]{4})"
var spechars = new RegExp("([- \(\)\.:]|\\s|" + delimiters + ")","gi") //Special characters to be removed from the link
var phonereg = new RegExp("((^|[^0-9])(href=[\"']tel:)?((?:" + phonedef + ")[\"'][^>]*?>)?(" + phonedef + ")($|[^0-9]))","gi")

function ReplacePhoneNumbers(oldhtml) {
//Created by Jon Meck at LunaMetrics.com - Version 1.0
var newhtml = oldhtml.replace(/href=['"]callto:/gi,'href="tel:')
newhtml = newhtml.replace(phonereg, function ($0, $1, $2, $3, $4, $5, $6) {
    if ($3) return $1;
    else if ($4) return $2+$4+$5+$6;
    else return $2+""+$5+""+$6; }); 
return newhtml;
}

$("#address").html(ReplacePhoneNumbers($("#address").html()))

$("a[href^='tel:']").click(function(event){
     event.preventDefault(); 

     link  = $(this).attr('href');
     tracklink = link.replace("tel:","")
     tracklink = tracklink.replace(spechars,"")
     if(tracklink.length == 10) {tracklink = "1" + tracklink}

     ga('send', 'event', 'Contact', 'Phone', tracklink);
     //_gaq.push(['_trackEvent', 'Contact', 'Phone', tracklink]);

     setTimeout(function() {
        window.location = link;
     },300);
});
}
})

A few notes here – again, you want to make sure this fires before your other link trackers, etc… because it will actually rewrite the content of that <div> or whatever container you specified. Also, to be more specific – this code will track when someone on a mobile device CLICKS on your phone number.  After that, most devices will usually pop up a message asking if you want to call the phone number or not. There’s no guarantee that someone actually went through the phone call – they may have canceled out or just added the phone number to their contacts.

Implementing with Google Tag Manager

With this javascript written and customized to how you like it, implementing it with Google Tag Manager should be a breeze. You can set up a custom macro to return whether or not the user is on mobile using the following javascript:

function() {
 if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
    return 'Yes';
 } else {
     return 'No';
 }
}

Then only fire this JavaScript on mobile pages.

If you wanted to use a Tag to fire the event, you can certainly do so. For simplicity, I did this all through a custom javascript Tag, but you could certainly add a link click listener and create a rule to look for any link clicked that begins with “tel:”, then use that to fire your Google Analytics Event.

Summary

Hopefully, this is helpful to some people! It’s not a perfect script, but it gets the job done. Let me know if you have any questions in the comments, or, since we’re talking about phone numbers, feel free to call us here at (877) 220-5862 for all of your Google Analytics or Google Tag Manager needs!

Here is a screenshot of my data after phone tracking was implemented. Name and numbers have been changed to protect the innocent, but it’s clear that phone numbers were a large interaction that we were previously missing for this particular client.  I’ve also combined Phone, Email, and Contact Form into one Event Category called “Contact” to help keep things organized.

Google Analytics screenshot with Phone Tracking enabled