Google Analytics without javascript!

Yes, it is possible to send data to Google Analytics without executing javascript! In this tutorial I will try to explain how this can be done and I will give some good examples. Server side analytics enables you to measure data like rss, image or pdf visits.

Analytics without javascript?
When you look at the analytics javascript code you see that it combines several sets of data into an image request. This image request sends the right data to Google (not the javascript). When you know what url you should use for the image, you can call the image directly and send the same data. Of course you need to be able to request the image url and that isn’t easy from another image, rss feed or pdf. This is why we request it “server side”.

Server side image requests
Javascript is “client side”; this means the browser does all the calculations and actions that the script requires. PHP, ASP, Perl and many others are server side scripting languages; which means the server that hosts the website does all required calculations. This means javascript knows more about the action of the user and PHP can easily request data from a database or other source.

PHP (I’ll focus on PHP in this example) can also request a file from the internet without executing or showing it. Just requesting the analytics image is enough to trigger a hit in your report and it will show up in your account. The downside of requesting the image from your server is: You lose the IP address and other data that Google records at the moment the image is requested. The server IP of your web server will be recorded.

Server side requests in a client side report will obscure your data. Create a separate Analytics profile for everything you log server side.

Who requests my RSS feed?
RSS feeds don’t execute javascript, but in some feed readers you can execute javascript once a post is read. This is why you need to log requests of your RSS XML file differently. You can either use a service like Feedburner or send an Analytics image request from PHP or ASP. The following example shows how you send specific data to Google Analytics from your RSS in PHP.

  1. Create a new analytics profile with its own tracking code (not a copy of an existing profile). Activate the profile by temporarily changing the code on your homepage. After activating you return it to the original one.
  2. Add the following PHP code to the file that produces your RSS (preferably at the bottom): urchin-image.txt
  3. Update the urchin code, domain, user defined variable (if desired) and the fake page request you’d like to track.
  4. I left all the other data intact because it works with them and they don’t impact the report, but when I have time I can probably clean it up some more.

Tracking PDF or Image requests
The script that produces your RSS feed is already executing PHP code. Images and PDF files don’t execute anything, so you need to add something extra to track these in a similar way. The following code shows you how you can request an image, PDF, SWF or for instance downloads and request the Google Analytics (Urchin) code at the same time.

  1. Find out if your server supports mod_rewrite. If it does, you can produce cleaner URLs. As a RewriteRule in your htaccess you add something like: “RewriteRule ^tracker/(.*).gif$ /tracker.php?url=$1&filetype=gif [L]“. This requests the file tracker.php whenever a gif image from the (non-existing) directory tracker is requested. You can do the same with all other filetypes that don’t execute PHP code themselves.
  2. Create tracker.php and add something like the following code: tracker.txt. Customize the script where needed and add content type headers for everything you’ve added to the htaccess.
  3. Now you can open the extra profile you should have created and under “Content Optimization > Content Performance > Content Drilldown” you find the directory “tracker” with all image/file requests logged in it.

Here are all values you can fill: image-url-explained.txt

Most of the information needed for the statistics is gathered by the javascript file (and you can influence that data), but the other half is collected when the image is requested from the Google server. This means that that information belongs to your server and not to the user that did the real request. Converting server-side to client-side analytics is very usefull, but not flawless. I haven’t seen this type of Analytics tweak anywhere else, so please let me know if you would like me to post more similar tweaks or more information in the future.

Google Analytics is very good once you implement some of the following tweaks.

37 Responses to “Google Analytics without javascript!”

  1. I was waiting for this post since the day you mentioned it on my site ;)

    Interesting technique for measuring image en PDF requests, but I doubt if it will give you good reports for RSS. Some webbased RSS readers fetch your feed once every half hour for maybe a thousand readers.

  2. Gerben says:

    But isn’t it so, that you already can measure pdf downloads, and perhaps even image requests with the current analytics codes?

    So with the javascript?

  3. Images and PDF links from within your website can be measured by adding an onclick event to the links. But I have some PDF files that score in Google, are linked to by other websites and are downloaded frequently. Without javascript execution it is harder to measure these requests. I do have server logs that show me much information, but now you can also use Analytics to report on this.

    For RSS feeds this only shows you how many scripts or stand alone readers import your feed. This is important if you want to measure subscriptions, but clicks from RSS readers are more easily measured by using a separate URL or an Analytics campaign tracker.

    I have a more advanced version of the published script that tracks every PHP $_SERVER variable into the right Analytics image variable, but I’m still finetuning it and wanted André to at least see what I’ve got so far. I just have to find more time for the advanced version. And since I started my own company, time is hard to find.

  4. The script has been updated so the cookie information keeps up to date and the script keeps working (my previous example expired).

  5. Sampsa Suoninen says:

    I haven’t yet read your noscript-version, but it’s very useful if you want to track users who don’t enable JavaScript on your site. For RSS tracking I don’t find it useful for the reasons André mentioned. Adding tracking to the RSS link on the other hand is quite useful.

    For tracking PDF and other downloads, I prefer to use the onClick-event, but on some cases (like mobile users) I find your code to be quite valuable.

    A job well done ;)

  6. matt says:

    Hi, I’m about to implement your suggestions, but just wanted to say *thank you* for sharing this information.

    The biggest need for non-javascript GA support is I believe for widget / blog-parts – which are increasing in popularity and use across the Internet. Because these widgets / blog-parts are run from 3rd-person clients and widget / blog-part provider can’t expect to send the entire urchin javascript to these clients, so far the only viable work-around is a non-javascript method of adding data to GA.

    Please continue to share your tweaks on GA (esp. non-javascript ones)!

  7. Just wanted to drop a line and say thank you for this. I am going to implement and see how it works out. One thing i am concerned about is when putting this on high traffic pages; how will php handle the extra load.

  8. @Zigzo: PHP can handle quite alot and this is no heavy burden. But when will you need to use this for high traffic pages? It is mainly meant for pages that don’t support javascript or visitors that don’t. Normal visitors will still get the Javascript version of GA. Images that aren’t loaded from a tracked page, RSS feeds, PDF, etc.

  9. I’ve recently build a Flash actionscript version of the GA code. Why doesn’t Google create one?

  10. forkmantis says:

    I’m using the onclick javascript to track downloaded files from links on my site. However, our client often sends out email with links directly to the files, which bypasses GA altogether. I found your page looking for some way to log data to GA from the server side. I was pretty happy with your solution, except for losing the visitor data.

    Your mention of mod_rewrite gave me an idea. Rather than using mod_rewrite to invoke a server side call to GA, why not use it to ensure that the client executes the GA javascript, and collect all of the visitor info in the process?

    Using RewriteCond on the HTTP_REFERER, I check to see if the request was local, or external. If local, I can safely assume it’s already been logged to GA w/ the onclick script, and not rewrite the URL. If the referer was not from my site, then I use mod_rewrite to redirect to a “Your file download will begin shortly” wrapper page, w/ the proper GA code. I just have a 1 second meta-refresh on the page that sends the file to the user.

  11. @forkmantis: Yes that would work. Currently i’m doing the same from the used PHP file because I want to condition the choice to track or not on multiple variables. Referer is one of those variables, but I also check for bots and other stuff.

  12. Vince says:

    Hi Peter,

    Good post! I want to setup google analytics on my (php generated) mobile pages. Since most mobile devices don’t support javascript I want to implement it using your server side php solution.

    Your stating that the server IP will appear since the call is made from my server, can’t I just grab the necessary variables from the user such as IP, hostname, user agent etc and then do the post to google analytics?

    If you have any ideas on this one let me know!

    Thanks!

    Vince

  13. The Google Analytics image request URL doesn’t yet support the IP variable (it is detected on Google’s side), but I recently placed a request with Google. Hopefully they will introduce it soon.

    User agent is an image variable that is normally detected by Javascript, so you can overwrite that one.

    The best sollution is to save visitor IP to a variable like “User Defined” and then create a filter that ports that variable to the “Visitor IP Address”

  14. Apart from IP variable problem, this code really rocks! I’ll bookmark this page to see if there’s any progress on the IP.

    About your temporary solution, do you mean that it’s possible to send this IP variable along with $var_uservar and then create a filter in GA? And is GA able to create nice (country/location) graphics with this filter then ?

  15. Yes, it is possible to overwrite many variables with GA filters and from that point onwards all graphs based on those variables change as well. The IP is the only one I haven’t tried to overwrite yet, but it is present in the filter list! Let me know if it works.

  16. Motivator says:

    I have installed this script and write redirects but have problem.

    Script returns needed file but with incorrect name.

    E.g. file: test.zip

    In Opera sript returns file tracker.zip
    In IE script returns file tracker.php

    Any suggestions? Why?

  17. Karthik says:

    Fish,
    I faced this problem for my flash based widget. A better approach is to construct the embeddable code as a iframe rather than the as a flash object. Let the iframe source be a PHP page called EmbedSource.php, which is hosted on your server. This PHP should return the HTML for the embedded flash movie. So, whenever the iframe is rendered on any of your user’s page, your EmbedSource.php will get a request whose referral would be the hosting page. Use that url for tracking. If you use the user defined variable’s slot, you won’t get a consolidated statistics of referrals.

    Regards,
    Karthik

  18. Tomasz says:

    How about printing the urchin image HTML tag to the browser from PHP, wouldn’t that work to get more accurate client data for Mobile browsers, non-javascript browsers etc. ? Has anyone tried this?

  19. Ophir Prusak says:

    Kudos!

    I’ve just been looking into importing some external data in GA and this seems to be the solution I’ve been looking for.

  20. bmjnine says:

    thank you — exactly what i was looking for to track software installation. our installer program makes a URL request to report its status, and other installation variables, but the request is obviously not made through a browser, therefore, no javascript. this workaround is working well for me. i actually contacted GA support before finding this, and they said GA w/o javascript cannot be done, so there you go.

    note: to use the latest version of GA (”ga.js” version, as opposed to the old “urchin.js” version), just update the utmwv=3 (instead of utmwv=1).

  21. Robert says:

    Hi Peter,

    Any chance us flashers might get a peek at your actionscript version so I don’t reinvent the wheel?

    Thanks
    Robert

  22. The Flash code was created for a company that will offer it to their customers. I don’t have the rights, but I told them it would be a great linkbait for them to offer it for free. So far they reacted negatively and they want to keep it as their own USP.

    It is however fairly easy to create one and I’ll gladly offer some free advice. The real problem is in linking (fake) urls to different actions in your Flash animation.

  23. Scott says:

    Has anyone figured out how to track user IP’s and agents using this method? I really need to be able to assign the true user IP to each request, not the server’s IP. If you’re using a filter to remap a user variable, a pointer to how to modify the GA call and what to do in the GA filter panel would be appreciated :) .

  24. [...] That’s pretty much what I’ve seen. Some of those actions are obviously first generation Javascript-capable bots that are easily identified (BTW, Javascript-support isn’t actually required, but it makes the life of the hacker considerably easier). What’s a bit scary are the “better bad bots” that blend in with human traffic. Without taking unusual measures, the only way to tell the bot traffic from real traffic is when they slip up and don’t understand typical traffic patterns for the sites they’re sending fake traffic to, or otherwise act in ways only bots would act (like asking for the same page 1,000 times). [...]

  25. [...] The theory behind this approach is that the bots may not actually execute the Javascript, they may see the tracking code on your page, recognize it as a tracking code, grab your Google Analytics ID and do a programmatic call to Google Analytics (as described by Peter van der Graff). In this case, if you’ve set a segmentation value, they most likely won’t be programmed to detect that and as a result they’ll show up on your reports as “not set”. [...]

  26. [...] Linklove » Google Analytics without javascript! server side analytics enables you to measure data like rss, image or pdf visits (tags: analytics tips tutorial) [...]

  27. Saviz says:

    Peter,
    This is an excellent article. Thanks for writing it. I am planning on incorporating this idea. I’m working on the client side but due to certain limitation I’m not able to use Javascript as intended by Google so I’m going to use your idea of using an image. My question is how can I ensure that the unique vs. repeat visitors are recognized. Does the method you recommend allow that to happen. I tried this once before awhile back and image pings couldn’t figure out unique vs. repeat visitors. Can you comment on which portion of your code takes care of that.

  28. Saviz says:

    Also do you know where I can find a list of the paremeters that need to be set and what they mean for the image analytic. Thanks again for your blog.

  29. Cookie information is also communicated though the image URL and IP address can be communicated through the user defined variable and then transfered to the IP address field with a custom filter. It takes some tweaking, but identifying repeat visitors can be done.

    I don’t have a full list of variables, but you don’t need them all.
    http://www.vdgraaf.info/wp-content/uploads/tracker.txt contains the most important ones.

  30. [...] Allereerst credits voor Peter van de Graaf die een tijdje geleden een post op zijn weblog maakte over de exacte techniek die benodigd is. Met PHP worden zo veel mogelijk gegevens verzameld die een aanroep aan Google Analytics mogelijk maken. Vervolgens wordt vanaf de webserver het Google Analytics plaatje opgevraagd en is de meting gereed. [...]

  31. forkmantis says:

    Out of curiosity, does the new ga.js allow you to pass values for things such as user_agent or host, or do you still have to use custom fields for this?

  32. [...] (Note: I wanted to insert a handy little flow chart of how javascript analytics works but couldn’t find one! If anyone knows of one, please drop a link in the comments and I’ll add it into the post. There’s a bit more in-depth explanation of how it works here though.) [...]

  33. [...] (Note: I wanted to insert a handy little flow chart of how javascript analytics works but couldn’t find one! If anyone knows of one, please drop a link in the comments and I’ll add it into the post. There’s a bit more in-depth explanation of how it works here though.) [...]

  34. jan says:

    Hi,

    Great Idea, Does this work for the newest GA Version Code (ga.js)?

    regards, jan

  35. Jérémy says:

    Hi,
    have you got a tutorial wich explain how to track with google tag without javascript ? I use the lastest version of google tag and I want to implement it using your server side php solution !

    Thank you for HELP !

  36. The newest ga.js tag is little different in the available variables it sends. This post is very old and I don’t offer any support or Analytics help, but the code still works.

    It should be used as an example to get you thinking differently about client-side analytics, not as a code to “copy and paste and you’re done”. I hope my post is a step in the right direction and feel free to create fantastic scripts to share yourself. The amount of people interested in this post is enormous, so you should get a lot of visitors by creating the sequal!