diff --git googleanalytics.module googleanalytics.module
index 62c888e..8ea1c6f 100644
--- googleanalytics.module
+++ googleanalytics.module
@@ -66,7 +66,15 @@ function googleanalytics_menu() {
     'type' => MENU_NORMAL_ITEM,
     'file' => 'googleanalytics.admin.inc',
   );
-
+  $directory_path = variable_get('file_public_path', conf_path() . '/files');
+
+  $items[$directory_path . "/googleanalytics/%"] = array(
+    'title' => "Fetches, writes and serves google analytics JavaScript",
+    'page callback' => 'googleanalytics_cache_js',
+    'page arguments' => array(count(explode('/', $directory_path)) + 1),
+    'access callback' => TRUE,
+    'type' => MENU_CALLBACK,
+  );
   return $items;
 }
 
@@ -261,7 +269,22 @@ function googleanalytics_page_alter(&$page) {
     $script .= 'ga.async = true;';
 
     // Should a local cached copy of ga.js be used?
-    if (variable_get('googleanalytics_cache', 0) && $url = _googleanalytics_cache('http://www.google-analytics.com/ga.js')) {
+    if (variable_get('googleanalytics_cache', 0)) {
+      $location = 'http://www.google-analytics.com/ga.js';
+      if (variable_get('clean_url', 0)) {
+        // If the cached js doesn't exist, it will always be available
+        // due to the menu callback.
+        $path = 'public://googleanalytics';
+        $file_destination = $path . '/' . basename($location);
+        $url = file_create_url($file_destination);
+      }
+      else {
+        // However if clean URLs are not available, the menu callback and
+        // file location will be different, so fall back to generating the
+        // file inline if it doesn't already exist.
+        $url = _googleanalytics_cache($location);
+      }
+
       // A dummy query-string is added to filenames, to gain control over
       // browser-caching. The string changes on every update or full cache
       // flush, forcing browsers to load a new copy of the files, as the
@@ -341,6 +364,45 @@ function googleanalytics_cron() {
 }
 
 /**
+ * Menu callback to fetch and cache google analytics js if it doesn't already exist.
+ */
+function googleanalytics_cache_js($filename) {
+  $location = 'http://www.google-analytics.com/ga.js';
+  $basename = basename($location);
+  // If a file other than $location is requested from this URL, exit immediately.
+  if ($filename != $basename) {
+    drupal_add_http_header('Status', '503 Service Unavailable');
+    print 'Invalid request';
+    exit;
+  }
+  else {
+    $path = 'public://googleanalytics';
+    $file_destination = $path . '/' . $basename;
+    if (!file_exists($file_destination)) {
+      _googleanalytics_cache($location);
+    }
+    $js = file_get_contents($file_destination);
+    $content_type = 'application/javascript';
+    $headers = array();
+    $headers['Content-Type'] = $content_type;
+    // Ensure this file can be cached by browsers and reverse proxies.
+    $headers['Cache-Control'] = 'public, max-age=1209600';
+    // Since the file name is based on a hash of file contents, there is no
+    // problem allowing the browser to cache it for as long as possible.
+    // Set this to two weeks since that's what .htaccess does if mod_expires
+    // is enabled.
+    $headers['Expires'] = gmdate(DATE_RFC1123, REQUEST_TIME + 1209600);
+
+    // When possible, serve the gzip version of the file via PHP.
+    foreach ($headers as $key => $value) {
+      drupal_add_http_header($key, $value);
+    }
+    print $js;
+    drupal_exit();
+  }
+}
+
+/**
  * Download/Synchronize/Cache tracking code file locally.
  *
  * @param $location
