GOOGLE CONFIDENTIAL AND PROPRIETARY
Do not distribute without written consent and authorization from Google Inc.
Google Gadget Ads have not been officially launched to the public.

How to Build a Google Gadget Ad

Introduction

This tutorial takes you through the various steps to create a gadget ad. We'll describe how to get started and cover various ways to include interesting content in your gadget. Lastly, we'll work through a case study using one of our existing gadget ads, taking you step-by-step through building it as if it's being built for the first time. At the end, you'll have a higher level of understanding of gadgets, how they work, and how to begin writing your own effective gadget ads. We also recommend using the gadget scratch pad as you follow along with the examples below.

Gadget Ads vs. Google Gadgets

Gadget Ads are simply Google Gadgets with rich-interactive content designed to attract users to a product. Architecturally, they're exactly the same. The only new concept introduced is the clickurl, discussed further below, used to track user clicks inside the ad. Like Google Gadgets, once a gadget ad is created, it can be distributed and added to Google Personalized Homepage, Google Desktop, blogs, websites, etc. Since gadget ads and Google Gadgets are created in more or less the same way, we highly recommend familiarizing yourself with the Google Gadgets API documentation. Understanding what gadgets are, how they work, and what features are available can significantly increase your ability to create high-quality gadget ads that are capable of reaching millions of users.

Getting Started

The personalized homepage is a great place to develop and test your gadget. There are a few things to do before you can begin designing your gadget. These simple instructions take you through the initial steps.

Add the Developer Gadget

The developer gadget acts a "command center" for all gadgets on your personalized homepage. In addition to listing all the gadgets that you're running, it lets you add, view, and manage gadgets. The developer gadget provides features that you'll need when developing your gadget such as disabling gadget caching. This prevents your gadget from being cached and lets you see your changes immediately.

Go ahead and add the developer gadget. For more information, visit the documentation.

Create an Empty Gadget

First, you'll want to add a new blank gadget to your homepage. We're not worried about content, so the gadget can initially be empty.

Using a text editor of your choice, copy and paste the gadget template below into a file, save it, and upload it to your public web server:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="My First Gadget Ad"/>
  <UserPref name="clickurl" datatype="hidden" default_value=""/>
  <Content type="html"><![CDATA[
    ALL HTML CONTENT GOES HERE
  ]]></Content>
</Module>

Gadget content is simply HTML and should be added between the opening and closing CDATA tags. Everything inside here represents gadget ad content and can contain any valid HTML syntax.

Disable Caching

After the gadget is uploaded, add it to your homepage using the developer gadget. Using the developer gadget, disable caching for your newly-added gadget. This ensures that your changes will immediately be visible while developing your gadget. Once this is done, you can make changes to the gadget and re-upload it to the hosting server. You can simply reload the homepage to see the changes you made.

Set the Width and Height

Set gadget dimensions early on so you can figure out the best way to layout your content inside the gadget. Under ModulePrefs, the width and height should be specified in number of pixels:

<ModulePrefs title="My First Gadget Ad" width="250" height="200"/>

Defining the Click URL

The click URL is a mechanism used to track user-interaction inside a gadget ad. It should be included in the gadget XML as a hidden UserPref named clickurl. All click URLs should end with an open URL parameter, &url= which will be used to append the target destination for tracked links in your gadget.

We provide a test click URL that you can use when developing your gadget ad. Instead of sending real clicks to the ads database, it'll create a simple pop-up that displays the target destination. This is useful when you want to verify that your links are tracking correctly and that requests are correctly being sent to the click URL.

<UserPref name="clickurl" datatype="hidden" default_value="http://gadgetads.googlecode.com/svn/trunk/test_clickurl.html?url="/>

Make note of this test click URL as you will be using while developing your gadget ads:
http://gadgetads.googlecode.com/svn/trunk/test_clickurl.html?url=

Experiment: Test the Click URL

The links below are all set to route through the test click URL described above. Try clicking on a few to see the confirmation pop-up which confirms click-thrus are being tracked properly. If you setup click URLs correctly in your gadget, then you should see similar results:

How To Use the Click URL

Once again, gadget content is simply made up of HTML. So traditionally, the way you'd create a link in HTML is by creating an anchor tag that looks something like this:

<a target="_top" href="http://mytargetdomain.com">Target Link</a>

However, this link won't be tracked by the ads system because it didn't go through the clickurl. Instead, you'll need to use JavaScript to generate and assign the URL to these links. There are various ways to do this, but here's one simple step-by-step overview to get you started:
  1. Create an id attribute in your anchor tag and assign it a unique value. The href attribute should also contain the target destination.
    <a id="link1" target="_top" href="http://mytargetdomain.com">Target Link</a>
  2. Setup an event handler function using _IG_RegisterOnloadHandler(func). This method accepts a single argument, which is a function that gets called after the entire gadget loads. This is recommended to ensure that all anchor tags defined in step 1 are rendered before generating and assigning new URLs to them.
    <script>
      _IG_RegisterOnloadHandler(function() {
        // This will be executed after gadget loads
      });
    </script>
  3. Inside the event handler function, you can retrieve the clickurl using the _IG_Prefs object. Once you have the clickurl, generate the new trackable URL which is created by taking the existing value in href, escaping it, and appending it to the clickurl. You can then access the HTML DOM using _gel() and replace the current anchor tag's href attribute with the new URL.
    <script>
      _IG_RegisterOnloadHandler(function() {
        // Get anchor tag element 
        var link1 = _gel("link1");
        var prefs = new _IG_Prefs();
        var clickUrl = prefs.getString("clickurl");
        var trackableUrl = clickUrl + _esc(link1.href);
        
        // Replace the existing href attribute for link1 with the new URL
        link1.href = trackableUrl;
      });
    </script>

    Here's a more condensed version:
    <script>
      _IG_RegisterOnloadHandler(function() {
        var prefs = new _IG_Prefs();
        
        // Replace the existing href attribute for link1 with the new URL
        _gel("link1").href = prefs.getString("clickurl") + _esc(_gel("link1").href);
      });
    </script>

Getting Remote Content

One great feature of gadgets is the ability to fetch remote content from third-party websites and display it within your gadget. The API currently offers three different methods to do this, depending on the type of content being retrieved:

Example: Fetching from an Atom/RSS Feed

Here's an example where the first feed entry is fetched from the Google News Atom feed and returned as a JSON object. The callback function takes the response and outputs HTML generated from the entry title, link, and summary.

<div id="out"></div>
<script>
  _IG_RegisterOnloadHandler(function() {
    function callback(response) {
      // Retrieve first entry from the response
      var firstEntry = response.Entry[0];
      
      // Generate HTML using the entry's title, link, and summary
      _gel("out").innerHTML = [
        '<a href="' + firstEntry.Link + '">' + firstEntry.Title + '</a>',
        firstEntry.Summary,
      ].join("<br>");
    }
    
    // Fetch 1 entry from Google News Atom feed and include summaries
    _IG_FetchFeedAsJSON("http://news.google.com/?output=atom", callback, 1, true);
  });
</script>

Embedding Images: A Better Way

Gadget ads often embed high-quality images to create a visually appealing gadget. Each time the gadget is rendered, requests are sent out to retrieve each image from original hosting servers. This can significantly increase latency and gadget loading times, which can result in slower loading pages and a negative user experience. Fortunately, there is a feature that allows you to cache images on Google servers, which significantly improves gadget performance and loading times. This also dramatically reduces the load on the image hosting servers because of the significant decrease in number of requests.

There are two JavaScript functions available for this purpose:

In HTML, you'd typically embed an image like this:

<img src="http://www.google.com/intl/en_ALL/images/logo.gif"/>

However, to maximize performance benefits, here's the recommended way to embed images in your gadgets:

<img id="logoImg" src=""/>
<script>
  _IG_RegisterOnloadHandler(function() {
    _gel("logoImg").src = _IG_GetImageUrl("http://www.google.com/intl/en_ALL/images/logo.gif");
  });
</script>

Background Images

There are other ways you might include images in your gadgets besides using <img> tags. For example, you can use similar tactics for CSS background images:

<div id="panel">This content has a background image</div>
<script>
  _IG_RegisterOnloadHandler(function() {
    _gel("panel").style.background = "transparent url(" + _IG_GetImageUrl("http://www.google.com/intl/en_ALL/images/logo.gif") + ") 0px 0px no-repeat";
  });
</script>

Embedding Flash Content

Many times, you're going to want to embed Flash within your gadget. There are different ways to do this in HTML, and it can be a challenge to make it work across all browsers. As a result, we've created a cross-browser compatible Flash injection library that allows you to easily embed Flash content anywhere within your gadget.

To use the Flash library, simply add the following line under <ModulePrefs>:

<Require feature="flash" />

The Flash library currently includes the following methods:

Using our Flash library is the recommended way to embed Flash content in your gadget and ensures it works correctly across multiple browsers. Please visit the documentation for more information.

Example: Add a YouTube Video

Here's a classic example on how to embed a YouTube video in your gadget using the Flash library and setting a custom width and height:

<div id="container"></div>
<script>
_IG_EmbedFlash('http://www.youtube.com/v/_YUugB4IUl4', _gel('container'), {
    swf_version: 6,
    id: "flashid",
    width: 250,
    height: 200
  });
</script>

Caching Flash Content on Google

Similar to the way you cache gadget images, you can also cache embedded Flash content to improve gadget performance and decrease the load on hosting servers. To do this, you'll need to use _IG_EmbedFlash(url, container, opt_params) in conjunction with another method called _IG_GetCachedUrl(url), which simply returns the proxy URL for the cached version of the file specified by url.

Here's the same example from above. Instead we cache the embedded YouTube video:

_IG_EmbedFlash(_IG_GetCachedUrl('http://www.youtube.com/v/_YUugB4IUl4'), _gel('container'), {
  swf_version: 6,
  id: "flashid",
  width: 250,
  height: 200
});

Embedding Google Maps

It's easy to integrate a Google Map inside your gadgets using the Google Maps API. When using maps within gadgets, you don't need to sign up for a Google Maps API key, and you can simply add a reference to the maps JavaScript library to start using it.

Start Small

The Google Maps API is fairly large with a constantly growing set of functionality. If you've never used the API before, the easiest way to start learning is to work off a simple example and then build your way up. For example, here's a gadget that displays a small map centered on Palo Alto, CA (add it now):

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Sample Map">
  </ModulePrefs>
  <Content type="html">
  <![CDATA[
    <style>
      #map {
        width: 100%;
        height: 300px;
      }
    </style>
    <div id="map"></div>
    <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;"></script>
    <script>
      _IG_RegisterOnloadHandler(function() {
        if (GBrowserIsCompatible()) {
          var map = new GMap2(_gel('map'));
          map.addControl(new GSmallMapControl());
          map.addControl(new GMapTypeControl());
          map.setCenter(new GLatLng(37.4419, -122.1419), 13);
        }
      });
    </script>
  ]]> 
  </Content>
</Module>

Once you have a map within your gadget, reference the Google Maps API documentation and work your way up to more advanced techniques on how to build more functional maps. A great recommended learning tool is to view the source code of existing gadgets that uses Google Maps API. Here's a few that we recommend checking out:

Case Study: Simplified Gmail Gadget Ad

The Gmail gadget ad is an extremely successful gadget, receiving an average of 1.4 million pageviews per week. It can easily be added to your homepage or embedded on other webpages. The best way to learn to write successful gadget ads is by building one yourself. So let's build a simplified version of the Gmail gadget ad. We won't replicate all the functionality in the original gadget. However, by the end, you'll have created a gadget that includes a Gmail video, the branded logo, and a clickable link that allows users to sign up for a Gmail account.

Collecting Resources

When initially building a gadget, it's extremely helpful to know what resources are required to build your gadget. Resources can be any content in your gadget, like images, URLs, Flash objects, etc. Normally, you'd be responsible for finding and/or creating the resources required by your gadget. For this example, let's assume you created the resources listed here:

Starting from Scratch

We start with an empty gadget template. The background image is 300 x 250 pixels. Let's set the width and height of the gadget to 300 x 250 by setting the width and height attributes under ModulePrefs.

Since we're still in testing phase, let's also set the clickurl to http://gadgetads.googlecode.com/svn/trunk/test_clickurl.html?url=. Your gadget should look something like this:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Simple Gmail Gadget Ad" width="300" height="250"/>
  <UserPref name="clickurl" datatype="hidden" default_value="http://gadgetads.googlecode.com/svn/trunk/test_clickurl.html?url="/>
  <Content type="html"><![CDATA[
  ]]></Content>
</Module>

Create the Content Layout

The background image determines how and where gadget content will be laid out.. We want the Gmail video ad to be the highlight of this gadget. So let's make it occupy the main center area. The background image makes room for this. At the top of the image, there are two icons for 'Videos' and 'Secret Tips'. We won't be using them in this example, but we have some free space to the right of it. Let's place a link there that redirects users to the Gmail sign-up page.

In HTML, we can use tables to help us organize and overlay content above specific areas in the background image.

  1. Create an HTML table and set the background image to http://www.labpixies.com/gadgads/gmail/images/background.png. Set the table width to 300 pixels to match the width of the background image.
  2. Create two table rows, one for the top header, and one for the main content area. Set the height for the header row to 30, and set main content row height to the fill up the remainder, which comes out to around 220. The two rows should combine to completely fill up the gadget's entire vertical space.
  3. Temporarily enable table borders to help guide and verify that the header and main content rows are split correctly. Remember to remove them later on when they are no longer needed.

Your gadget should now look something like this:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Simple Gmail Gadget Ad" width="300" height="250"/>
  <UserPref name="clickurl" datatype="hidden" default_value="http://gadgetads.googlecode.com/svn/trunk/test_clickurl.html?url="/>
  <Content type="html"><![CDATA[
    <table width="300" id="main" border=1 cellspacing=0 cellpadding=0>
      <tr height="30">
        <td></td>
      </tr>
      <tr height="220">
        <td></td>
      </tr>
    </table>
    
    <script>
      _IG_RegisterOnloadHandler(function() {
        // Set the background image of the table
        _gel("main").style.background = "transparent url(" + _IG_GetImageUrl("http://www.labpixies.com/gadgads/gmail/images/background.png") + ")";
      });
    </script>
  ]]></Content>
</Module>

Add the Gmail Ad Video

In the main content row of the table, let's embed the Gmail video ad. This row has dimensions of 300 x 220 pixels. Make sure you set the width and height of the embedded video to fit inside these dimensions. Feel free to play around with video dimensions here to create more or less whitespace padding.

  1. Since we'll be using the Flash library to embed the YouTube video, add the <Require feature="flash"/> tag within <ModulePrefs>.
  2. Add a container element within the main table cell where the video will be injected.
  3. Set the vertical alignment of this table cell to top. This forces the video to align its top border with the very top of the cell, eliminating any whitespace in between.
  4. Lastly, add the _IG_EmbedFlash(...) code in JavaScript and remember to set the width and height of the embedded video to fit inside the gadget dimensions.
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Simple Gmail Gadget Ad" width="300" height="250">
    <Require feature="flash"/>
  </ModulePrefs>
  <UserPref name="clickurl" datatype="hidden" default_value="http://gadgetads.googlecode.com/svn/trunk/test_clickurl.html?url="/>
  <Content type="html"><![CDATA[
    <table width="300" id="main" border=0 cellspacing=0 cellpadding=0>
      <tr height="30">
        <td></td>
      </tr>
      <tr height="220">
        <td valign=top>
          <div id="video"></div>
        </td>
      </tr>
    </table>
    
    <script>
      _IG_RegisterOnloadHandler(function() {
        // Set the background image of the table
        _gel("main").style.background = "transparent url(" + _IG_GetImageUrl("http://www.labpixies.com/gadgads/gmail/images/background.png") + ")";
        
        // Embed the Gmail video from YouTube
        _IG_EmbedFlash("http://www.youtube.com/v/_YUugB4IUl4", _gel("video"), {
            width: 300,
            height: 210
          });
      });
    </script>
  ]]></Content>
</Module>

Insert the Gmail Sign-up Link

In the unused top-right corner, let's create a Gmail sign-up link that redirects users to a webpage where they can sign up for a Gmail account. We want the gadget ad to track clicks on this link. So we'll need to use the clickurl to help create the link.

In this example, the 'Videos' and 'Secret Tips' icons aren't used. To position the link to the right of these icons, we could simply add some left padding to the table cell which pushes the link towards the right past the icons. Experiment a bit to determine the right amount of padding needed. Since the table is 300 pixels wide, a good starting pointing would be around 200 pixels.

  1. Create a new anchor tag inside the table cell of the first row. Remember to assign it an id so we can later add the clickurl to it.
  2. Use the style attribute to add left padding to the table cell. Fine-tune the padding until the link is correctly positioned to the right of the two icons.
  3. If table borders are still enabled, disable them because we no longer need them.
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Simple Gmail Gadget Ad" width="300" height="250"/>
  <UserPref name="clickurl" datatype="hidden" default_value="http://gadgetads.googlecode.com/svn/trunk/test_clickurl.html?url="/>
  <Content type="html"><![CDATA[
    <table width="300" id="main" border=0 cellspacing=0 cellpadding=0>
      <tr height="30">
        <td style="padding-left: 190px; font-size: 12px;">
          <a id="signup" target="_top" href="http://mail.google.com/mail/help/open.html#utm_campaign=en&utm_source=en-ha-na-us-gadget&utm_medium=ha">Sign up for Gmail</a>
        </td>
      </tr>
      <tr height="220">        
        <td valign=top>
          <div id="video"></div>
        </td>
      </tr>
    </table>
    
    <script>
      _IG_RegisterOnloadHandler(function() {
        // Prepend the click URL to the sign-up link so it can be tracked by the ads system
        var prefs = new _IG_Prefs();
        _gel("signup").href = prefs.getString("clickurl") + _esc(_gel("signup").href);

        // Set the background image of the table
        _gel("main").style.background = "transparent url(" + _IG_GetImageUrl("http://www.labpixies.com/gadgads/gmail/images/background.png") + ")";
        
        // Embed the Gmail video from YouTube
        _IG_EmbedFlash("http://www.youtube.com/v/_YUugB4IUl4", _gel("video"), {
            width: 300,
            height: 210
          });
      });
    </script>
  ]]></Content>
</Module>

The Final Outcome

Congratulations! You've just made your first gadget ad. Here's a live running instance showing how the final gadget should look like (add it now):

Resources:

Build Gadgets Using the Scratch Pad

One of the quickest and easiest way to start writing gadgets is to use the scratch pad. The scratch pad contains two tabs: "Edit" and "Preview". The "Edit" tab includes a simple text editor that lets you edit the gadget XML. Clicking on "Preview" lets you instantly view live results of your changes, without ever leaving the webpage.

Underneath the scratch pad, there are links to other gadget ads. Clicking on any of them loads the gadget spec into the editor where you can view the XML, modify it, and preview the effects of your changes. The Hello World gadget is loaded by default.

There are different ways to use the scratch pad: