diff --git a/google_tag_manager.admin.inc b/google_tag_manager.admin.inc
index e1c0e5a..e1e7415 100644
--- a/google_tag_manager.admin.inc
+++ b/google_tag_manager.admin.inc
@@ -26,6 +26,8 @@
  * @package google_tag_manager
  */
 
+define('GOOGLE_TAG_MANAGER_TRACKFILES_EXTENSIONS', '7z|aac|arc|arj|asf|asx|avi|bin|csv|doc|exe|flv|gif|gz|gzip|hqx|jar|jpe?g|js|mp(2|3|4|e?g)|mov(ie)?|msi|msp|pdf|phps|png|ppt|qtm?|ra(m|r)?|sea|sit|tar|tgz|torrent|txt|wav|wma|wmv|wpd|xls|xml|z|zip');
+
 /**
  * Implements hook_admin_settings() for module settings configuration.
  * @param array $form_state
@@ -46,6 +48,44 @@ function google_tag_manager_admin_settings_form($form_state) {
 		'#type' => 'textfield',
 	);
 
+  // Links tracking.
+  $form['linktracking'] = array(
+    '#collapsed' => TRUE,
+    '#collapsible' => TRUE,
+    '#title' => t('Links tracking'),
+    '#tree' => TRUE,
+    '#type' => 'fieldset',
+  );
+
+  $form['linktracking']['google_tag_manager_trackoutbound'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Track clicks on outbound links'),
+    '#default_value' => variable_get('google_tag_manager_trackoutbound', 1),
+  );
+  $form['linktracking']['google_tag_manager_trackmailto'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Track clicks on mailto links'),
+    '#default_value' => variable_get('google_tag_manager_trackmailto', 1),
+  );
+  $form['linktracking']['google_tag_manager_trackfiles'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Track downloads (clicks on file links) for the following extensions'),
+    '#default_value' => variable_get('google_tag_manager_trackfiles', 1),
+  );
+  $form['linktracking']['google_tag_manager_trackfiles_extensions'] = array(
+    '#title' => t('List of download file extensions'),
+    '#title_display' => 'invisible',
+    '#type' => 'textfield',
+    '#default_value' => variable_get('google_tag_manager_trackfiles_extensions', GOOGLE_TAG_MANAGER_TRACKFILES_EXTENSIONS),
+    '#description' => t('A file extension list separated by the | character that will be tracked as download when clicked. Regular expressions are supported. For example: !extensions', array('!extensions' => GOOGLE_TAG_MANAGER_TRACKFILES_EXTENSIONS)),
+    '#maxlength' => 255,
+  );
+  $form['linktracking']['google_tag_manager_trackoutboundaspageview'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Track clicks on outbound links as page views'),
+    '#default_value' => variable_get('google_tag_manager_trackoutboundaspageview', 0),
+    '#description' => t('By default outbound links are tracked as <em>Events</em>. In rare situations like tracking of <em>Goals</em> it may be required to track outbound clicks as page views.'),
+  );
 	return system_settings_form($form);
 }
 
diff --git a/google_tag_manager.js b/google_tag_manager.js
new file mode 100644
index 0000000..143074a
--- /dev/null
+++ b/google_tag_manager.js
@@ -0,0 +1,90 @@
+(function ($) {
+
+  Drupal.behaviors.google_tag_manager = {
+    attach: function () { 
+      // Accepts a string; returns the string with regex metacharacters escaped. The returned string
+      // can safely be used at any point within a regex to match the provided literal string. Escaped
+      // characters are [ ] { } ( ) * + ? - . , \ ^ $ # and whitespace. The character | is excluded
+      // in this function as it's used to separate the domains names.
+      RegExp.escapeDomains = function(text) {
+        return (text) ? text.replace(/[-[\]{}()*+?.,\\^$#\s]/g, "\\$&") : '';
+      }
+
+      // Attach onclick event to document only and catch clicks on all elements.
+      $(document.body).click(function(event) {
+        // Catch the closest surrounding link of a clicked element.
+        $(event.target).closest("a,area").each(function() {
+
+          var gtm = Drupal.settings.gtm;
+          // Expression to check for absolute internal links.
+          var isInternal = new RegExp("^(https?):\/\/" + window.location.host, "i");
+          // Expression to check for special links like gotwo.module /go/* links.
+          var isInternalSpecial = new RegExp("(\/go\/.*)$", "i");
+          // Expression to check for download links.
+          var isDownload = new RegExp("\\.(" + gtm.trackDownloadExtensions + ")$", "i");
+          // Expression to check for the sites cross domains.
+          var isCrossDomain = new RegExp("^(https?|ftp|news|nntp|telnet|irc|ssh|sftp|webcal):\/\/.*(" + RegExp.escapeDomains(gtm.trackCrossDomains) + ")", "i");
+
+          // Is the clicked URL internal?
+          if (isInternal.test(this.href)) {
+            // Is download tracking activated and the file extension configured for download tracking?
+            if (gtm.trackDownload && isDownload.test(this.href)) {
+              // Download link clicked.
+              var extension = isDownload.exec(this.href);
+              dataLayer.push({
+                event : 'GAevent',
+                eventCategory : 'Downloads',
+                eventAction : extension[1].toUpperCase(),
+                eventLabel : this.href.replace(isInternal, '')
+              });
+            }
+            else if (isInternalSpecial.test(this.href)) {
+              dataLayer.push({
+                event : 'virtualPage',
+                eventCategory : 'internalUrl',
+                virtualUrl : this.href.replace(isInternal, '')
+              });
+            }
+          }
+          else {
+            if (gtm.trackMailto && $(this).is("a[href^=mailto:],area[href^=mailto:]")) {
+              // Mailto link clicked.
+              dataLayer.push({
+                event : 'GAevent',
+                eventCategory : 'Mails',
+                eventAction : 'Click',
+                eventLabel : this.href.substring(7)
+              });
+            }
+            else if (gtm.trackOutbound && this.href) {
+              if (gtm.trackDomainMode == 2 && isCrossDomain.test(this.href)) {
+                // Top-level cross domain clicked. document.location is handled by _link internally.
+                dataLayer.push({
+                  event : 'crossDomainLink',
+                  linkUrl : this.href
+                });
+              }
+              else if (gtm.trackOutboundAsPageview) {
+                // Track all external links as page views after URL cleanup.
+                // Currently required, if click should be tracked as goal.
+                dataLayer.push({
+                  'event' : 'outboundLink',
+                  'outboundLinkRef' : '/outbound/' + this.href.replace(/^(https?|ftp|news|nntp|telnet|irc|ssh|sftp|webcal):\/\//i, '').split('/').join('--')
+                });
+              }
+              else {
+                // External link clicked.
+                dataLayer.push({
+                  event : 'GAevent',
+                  eventCategory : 'Outbound links',
+                  eventAction : 'Click',
+                  eventLabel : this.href
+                });
+              }
+            }
+          }
+        });
+      });
+    }
+  }
+})(jQuery);
diff --git a/google_tag_manager.module b/google_tag_manager.module
index 26aa498..5ddda72 100644
--- a/google_tag_manager.module
+++ b/google_tag_manager.module
@@ -90,6 +90,33 @@ function google_tag_manager_page_alter(&$page) {
 			'#markup' => t($snippet),
 		);
 	}
+
+  // Add link tracking.
+  $link_settings = array();
+  if ($track_outbound = variable_get('google_tag_manager_trackoutbound', 1)) {
+    $link_settings['trackOutbound'] = $track_outbound;
+  }
+  if ($track_mailto = variable_get('google_tag_manager_trackmailto', 1)) {
+    $link_settings['trackMailto'] = $track_mailto;
+  }
+  if (($track_download = variable_get('google_tag_manager_trackfiles', 1)) && ($trackfiles_extensions = variable_get('google_tag_manager_trackfiles_extensions', GOOGLE_TAG_MANAGER_TRACKFILES_EXTENSIONS))) {
+    $link_settings['trackDownload'] = $track_download;
+    $link_settings['trackDownloadExtensions'] = $trackfiles_extensions;
+  }
+  if ($track_outbound_as_pageview = variable_get('google_tag_manager_trackoutboundaspageview', 0)) {
+    $link_settings['trackOutboundAsPageview'] = $track_outbound_as_pageview;
+  }
+  if ($track_domain_mode = variable_get('google_tag_manager_domain_mode', 0)) {
+    $link_settings['trackDomainMode'] = $track_domain_mode;
+  }
+  if ($track_cross_domains = variable_get('google_tag_manager_cross_domains', '')) {
+    $domains = preg_split('/(\r\n?|\n)/', $track_cross_domains);
+    $link_settings['trackCrossDomains'] = implode('|', $domains);
+  }
+  if (!empty($link_settings)) {
+    drupal_add_js(array('gtm' => $link_settings), 'setting');
+    drupal_add_js(drupal_get_path('module', 'google_tag_manager') . '/google_tag_manager.js');
+  }
 }
 
 /**
