Ad blockers have been around for some time now and are widely used. The question around the end of the “free internet” and the impact on sales is not a new topic, and I won’t discuss it here.
But as of September 16, 2015, ad blockers entered the world of iOS devices when Apple announced they would allow third-party development of “content blocking” apps in its new operating system, iOS 9. One of them, Crystal, became in a few days one of the most downloaded paid apps from the App Store.
Unfortunately for website owners, Crystal (and probably other content blockers) not only blocks ads from being displayed on Web pages, but in some cases can also prevent pages from rendering properly.
More importantly, Crystal intentionally blocks analytics scripts from being downloaded and therefore executed. Result? A visit to your site from an iOS 9 device using Crystal won’t be reported in your analytics platform.
Why This Is A Major Issue
I understand internet users not wanting to see ads cluttering a page. Yet we have to acknowledge that many companies depend on income from ads (but again, this is not the point here).
I can also understand users not wanting to send data back. In my opinion, however, sending analytics data (page view, device, operating system, geolocation, language and so on) is not in any way harming a user’s experience on the Web. Actually, it helps create a better internet. A great search experience not only stems from search engines being smarter but also from websites being optimized.
Websites need analytics data to understand how they can improve, what pages are performing well, who their audience is, where it is and more. The best websites out there in terms of user experience are the result of extensive A/B testing, which is impossible without analytics data.
Below are proposed solutions to solve rendering issues and to get analytics data back. But first, I’d like to quickly explain how ad blockers work.
How Ad-Blocking Apps/Plugins/Extensions Work
Thanks to the AdBlock Plus FAQ page and some testing of the Crystal app, we are able to understand better how these content blockers work and, therefore, find potential solutions.
There are two systems in place: element hiding and asset blocking.
Element hiding: Through DOM manipulation, the app (or extension) injects an inline <style> snippet into the Web page. This snippet simply applies a display:none rule to any HTML element on the page that is considered as advertising, such as <a> links to doubleclick.net, <div> and <span> elements including id or class attributes values like “pub_300x250,” “text-ad,” etc.
Asset blocking: Leveraging “content policies,” the program instructs the browser not to download an asset if its URL contains specific keywords.
Therefore, files coming from domains such as googlesyndication.com (used for AdSense) or files with a name — including, for example, “advert”– will be blocked from being downloaded by the browser.
In the case of Safari on iOS 9, if Crystal is enabled, resources from google-analytics.com or files named “omniture.js” or “analytics.js” will be blocked.
Source: Safari Web Inspector
What You Can Do If Your Web Pages Do Not Render Properly
If some parts of your pages do not render the way they should (outside of ads not being displayed, of course), there are a few things you can do.
Check your code. Now that you know what type of HTML elements or assets ad blockers prevent from being displayed or downloaded, review your code and look for HTML elements such as <div id=”text-ad1″> or assets like “offers.js.”
If the issue is bigger than that, such as a drop-down menu not working or images from your CDN not being displayed, you should contact the ad blocker developer. We, at Merkle, have a few clients that were able to have their issue fixed quickly by simply notifying the ad blocking app developer.
Lastly, you can detect the use of an ad blocker and display a message on your Web pages (using a nice banner at the top, not a pop-up, please) to warn your visitors that, due to their ad blocker, their experience on your site might be affected. Here is a very simple way to do this:
Detecting Ad Blockers: Code Example
Code explained:
Insert a “bait” on your page — something that you know the ad blocker will catch. In this case, a simple dot nested into a div element including a class=”pub_300x250″ attribute-value pair. If an ad blocker is enabled, this element won’t be displayed, so its height will be zero.
The JavaScript function will look at the height of your bait element. If it’s zero, then an ad blocker is enabled, and an alert is displayed.
How To Get Your Analytics Data Back
Now that you understand better how ad blockers work, here is what you can and should do for your analytics.
Crystal will keep Safari from downloading files from google-analytics.com and files named “omniture.js.”
I am sure you know where I am going here. The solution is quite simple: Download and host the analytics files locally and change their name. URLs such as www.example.com/ga.js or www.domain.com/omni.js are not blocked by Crystal at this point, but just in case of an update, I’d recommend using random names like “x5f4re8w6d.js.”
There is one caveat here for Google Analytics (GA). Google recommends not to reference local versions of the Google Analytics files. The only reason is that by referencing those files directly from Google Analytics’ domain, you ensure “that you get access to new features and product updates as they become available, giving you the most accurate data in your reports.”
What if you could host the file locally but also have the latest version of it all the time?
Of course, you could regularly check the file manually or implement a script that will compare your local file to the GA one on a daily basis. Maybe you could go even further and have your script update the file if necessary.
This can definitely work, but here is a simpler solution that might work for you. I am aware of the potential programmatic overhead for large websites, but let’s be honest, this is better than not receiving traffic data or having to update the file manually.
I’ll illustrate this solution with the exact implementation that I’ve done on our Technical SEO website.
Reference a local file, that doesn’t really exist, as the Google Analytics JavaScript file. Make sure not to name it “analytics.js”:
Google Analytics Code Snippet
Use Apache mod_rewrite (or your server type equivalent) to serve the right content when this file is requested.
Unfortunately, it appears to be complicated to use URL rewrites without redirects on external domains and if a redirect is in place the end-state URL (from google-analytics.com) will be blocked by Crystal.
Therefore, rewrite the .js file URL to a local file that contains a server-side function (I used PHP) to get the content of the original google-analytics.com JavaScript file.
Here is the rewrite rule in our .htaccess file:
.htaccess Rewrite Rule
And the PHP function in techseoga.php:
PHP file_get_contents() Function
When http://www.technicalseo.info/resources/js/techseoga.js is requested, the content of the file is always the content of http://www.google-analytics.com/analytics.js, real time.
For the reasons explained earlier, google-analytics.com’s server allows the file to be cached for two hours only. Make sure to replicate this setting for your local file:
Set caching headers with PHP
The site latency impact is minimal (if existent), and now we get the visits data from iOS 9 devices using Crystal.
Conclusion
If internet users do not want to see ads, content blocker apps and extensions are a viable solution. But those ad blockers should only be “ads” blockers. They shouldn’t prevent Web pages from rendering properly and should definitely not block analytics data from being sent.
I hope the solutions described above will work for your website and that ad blocking apps will be improved so we don’t have to spend time finding solutions to problems that should not exist.
Commenti