What is Ghost Referrer Spam?

I get a lot of questions from clients about odd traffic showing up in their Google Analytics accounts. Lately, most of the traffic has come from what many call "ghost referrer spam". I wanted to take a moment to explain:

  1. Where does ghost referrer spam show up in GA?
  2. How do the spammers do it?
  3. Why do they do it?
  4. How can you prevent it?

My hope is that I can help web site managers understand this, so I'll do my best to keep the technical jargon to a minimum.

Preventing Caching of Images, JavaScript, and CSS

If you ever use tools like YSlow or PageSpeed Insights for Chrome, you know that caching images, style sheets, and JavaScript is an important part of optimzing your website's performance. Both Yahoo and Google recommend that you set up "far-future expiration dates" via HTTP headers.

In Apache, you can accomplish this pretty easily with the following configuration in your site's file:

Debugging Multiple Sites / Projects in NetBeans and Xdebug

I use NetBeans / MAMP / Xdebug  with Chrome and Firefox in OSX for debugging PHP applications. I'm not a fan of IDEs in general; I find them to be pretty clunky and slow. But I really like having breakpoints and a nice debugger window with stack and variable inspectors.

Enhancing the editor's experience: Using DIVs in a WYSIWYG Drupal editor

One of the biggest challenges we face as web developers is creating effective site management environments for our clients—a comprehensive system that balances content editing flexibility and ease of use, while still maintaining some semblance of web standards in the output. I want to show you a simple trick I've employed to enhance the editing tools: Making divs a bit easier to comprehend and use.

In this example, I'm using Drupal and ckeditor.

First, a bit of background.

Surge in referrals from

Recently, a client alerted me to the fact that they had a big surge in referral traffic from from February through early April, 2014. After April 1, that traffic dropped back down to zero:


Hiding Development and Staging Sites from Search Engines

Last year, I wrote an article about preventing my development and staging sites from turning up in search engines. Since I wrote that article, I've fine-tuned my procedures into a couple very simple, flexible practices that work within a number of environments.

My criteria for this topic are:

Merging Table Cells via jQuery / JavaScript

I'm currently working on a web site in which I need to merge some data cells within a bunch of tables.

The site is mostly product-oriented. It contains more than 100 product pages, each containing a data table showing the variations of that product family. There are certain data cells that will be identical to the same cell in the previous row. We would like to merge these cells visually, but we also want to retain the original HTML. (We will be using these tables in a related web application—served via Drupal web services.)

Here is a sample of the product data:

Lazy Lazy Image Loader for jQuery Mobile

Technically, this article isn't really about a lazy loader for images. Rather, it's my lazy man's version of a lazy loader. :) It's simple and effective for what I needed.

Multiple Login Sessions in a Single Browser

One of the tasks that web application and CMS developers run into daily is testing a site as several different types of users. Say you're developing an application or Drupal site that serves annonymous users, authenticated users, and various levels of administrators. Each user experience is different, and it's very time consuming to switch between user types in order to develop and test.

There are a few ways to do this:

jQuery for Uppercase and Mixed Case on a Large Drupal Site

I ran across an HTML/CSS challenge recently on a fairly large Drupal site (~ 400 pages). The designer specified using all-caps for headings and menu items. Naturally, using all-caps is a design decision that depends on the typeface, font size, kerning, etc. Typically, I don't care for all-cap text; but in this case, it was the right call. The catch (which we learned deep into the development process) was that the client wanted certain branded words and phrases to remain in mixed case.