Creating embedabble widgets

Distribution of embeddable widgets is a common feature in many web services today. The most well known example is probably google’s adsense that allows site owners to add google ads to their sites. Embeddable widgets allow a subset of functionality to be used on third-party sites, greatly increasing possible market reach for a web service / application.

What is a [web] widget

… a web widget is a portable chunk of code that can be installed and executed within any separate HTML-based web page by an end user without requiring additional compilation.
Web widget by Wikipedia

Put simply, we need to provide prospective site owners with a short piece of code (henceforth, the “embed code”) that they can place on their sites and have the widget appear without any additional modifications to the site.

How would we go about creating an embeddable widget?

Cross-site scripting (XSS)

Cross-site scripting is more often mentioned as a web vulnerability which uses the same technique maliciously to manipulate the target site. In this case, Javascript will be used to create the widget on the host site and not to attack it (you should always beware of including scripts from untrusted sources).

This technique is based on embedding a script <tag> on the host site that will refer to a script residing on your service. The script should then dynamically create the widget on the host site by manipulating the DOM and adding stylesheets and script tags as needed. Dr. Nic gives a nice overview of this technique in this detailed tutorial.

As the tutorial mentions, your embeddable script should have a unique namespace to avoid colliding with local scripts on the host site. Don’t be shy to use a long and verbose name for this purpose. Example:

;(function() {
	var techfounder_super_embed = window.techfounder_super_embed = {
		init: function() {

Some quick notes:

  • I used a self executing anonymous function. This allows me to declare additional variables and functions other than my main namespace (‘techfounder_super_embed’ in this case) without polluting the main scope or interferring with existing code on the site.
  • In order for the main namespace to be available outside of the anonymous function scope, I attach it to the window object.
  • I preceded the function with a semi-colon to close any potentially open Javascript statement that might have been loaded before it, which would have resulted in an error.

As opposed to the advice given in Dr. Nic’s article, I usually opt to use an external library such as jQuery, in order to better account for cross-browser differences as well as leverage the power inherent in such libraries. jQuery in particular has the useful noConflict() method which allows it to work side-by-side with other libraries, and can be loaded from a google CDN so it does not add bandwidth load on your server.

As for retrieving data cross-site (from your service server to the host site), there are 3 paths you could take:

  • Embedding extra script tags which include JSON data that is constructed dynamically (as shown in Dr. Nic’s tutorial).
  • Creating an Iframe element that accesses a remote resource (ie, on your server) to retrieve the data, and then passing the data back to the document.
  • Using a JSONP call to simulate a cross-site AJAX request. I personally opt for this technique as I find it the most elegant. jQuery supports this natively in recent versions, making it almost too easy to implement.

An important note to keep in mind that styling the widget elements should be done very explicitly. As the widget is embedded directly into the host document it could be affected by any previously loaded stylesheets. A good start would be to use a CSS reset (such as this one by Eric Meyer) and apply it directly to a unique ID that identifies the base widget element.

Iframe embedding

An Iframe is the most direct approach to including content from a remote site. It’s easy to pass arguments in the Iframe source URL and have a response dynamically built in return. However the Iframe approach suffers from some limitations:

  • You have to specify the Iframe proportions in the embed code and it should match the content exactly, else the content can get truncated. This also means the embed code would need to change if the widget appearance changes (which comes up often for customizable widgets).
  • There are some security limitations for Iframe scripting, so if you need to manipulate the host site page in any additional way,  you would need to include a script <tag> as well in the initial embed code to bypass the security restrictions.
  • Iframes are invalid markup in XHTML Strict doctype. Depending on the host site doctype declaration, this could present a minor issue (if the host site owner is concerned about with valid markup).

A big advantage in using an Iframe over directly embedding the widget in the host page is that you don’t have to be concerned with external styles affecting the widget.

Which should you use

Cross site scripting is useful when there is a need to dynamically manipulate the host site page. This would include placing the widget in positions different to where the embed code was placed at, offering additional user-interface interactions or communicating data back to your server (as Google analytics does, for example).

The Iframe approach is useful when you can tell ahead of time the exact size of the embedded widget, and you only want it to display content and not offer any Javascript interactions that occur outside of the Iframe.

To know when the next article is published, please subscribe to new articles using your Email below or follow me on Twitter.

Subscribe to Blog via Email

Enter your email address to receive notification about new posts.