Ziggeo Invents API Customer Acquisition Tool – and Freaks Out Customers

How do you make a real impression on potential API customers? Use our Bookmarklet system and customers will be stunned. Ziggeo has invented a new way to demonstrate to customers the effectiveness of its API -- customers actually see the technology at work on customers’ own sites -- or so they think. Our system simulates what their site would look like if our technology were installed. And sometimes think we've messed with their site -- it freaks them out. Ziggeo has developed code to overlay onto a a customer’s website/platform to create a working mockup -- a demo in which the API appears to be fully integrated into the customer’s site/platform. Here are the technical details for creating this working mockup: Instead of copying the target page, we create a so-called bookmarklet that modifies the page in-place on the client-side. What is a bookmarklet? A bookmarklet is a bookmark that contains javascript instead of a url. When you click on a bookmarklet while being on a website, the javascript is injected into the website and executed in the context of the website. This javascript code can now load other scripts and files dynamically and modify the page in-place, similar to a single-page app. There are a couple of caveats that you need to be aware of when developing a bookmarklet:
  • Some browsers restrict the length of a bookmark's body somewhere around 2048 characters. This means that you cannot load everything using your bookmarklet. All your bookmarklet will do is to load a secondary script from a different source.
  • You cannot easily load additional html (but we'll show you a way to do it).
  • Your environment is hostile (or fragile, depending on your pov), meaning that there are already javascripts running that might collide with libraries that you are loading. Also, the host site's css might be interfering with your css.
Preparations You need a webserver that can serve additional assets and scripts that you want to load into the host site. This can be an Apache webserver, nginx, some Heroku-hosted thingamajig, a Github page, a Dropbox public page, really any kind of webserver. Let's assume for the purpose of this tutorial that the url to your webserver is webserver.com. Also, let's call the very first script that we'll be loading into the host website by the bookmarklet scripts.js, i.e. http://webserver.com/scripts.js will serve up that script. Note that if the host website is using https, your server needs to support https as well, otherwise we might not be able to inject the script. Step 1: Creating the bookmarklet The bookmarklet code's objective is to, once injected into the host site, to load an additional javascript. Our code will add a script element to the body in order to load the file. [code lang="js"] document.body.appendChild(document.createElement("script")).src="//webserver.com/scripts.js" [/code] Since our bookmarklet is like a url (strictly speaking), we need to encode the javascript once we are done and prefix it with "javascript:". We can use a service like this one: [code lang="html"] javascript:document.body.appendChild(document.createElement(%22script%22)).src%3D%22%2F%2Fwebserver.com%2Fscripts.js%22 [/code] Bookmarklet Step 2: Creating the remote script Our remote script file can now really do anything on the host site. We should use closures so we don't interfere too much with the host website. [code lang="js"] (function () {   // Code in here }).call(); [/code] Step 2a: Loading additional javascripts If you want to load additional javascript files in your script, you need to load them dynamically. Since dynamically loaded javascript files are loaded asynchronously by the browser, you'll need to provide a callback function that will be called once the remote script has been loaded: [code lang="js"]    var loadScript = function (url, callback, context) {        var executed = false;        var head = document.getElementsByTagName("head")[0];        var script = document.createElement("script");        script.src = url;        script.onload = script.onreadystatechange = function() {            if (!executed && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete")) {                executed = true;                script.onload = script.onreadystatechange = null;                if (callback)                    callback.apply(context || this, [url]);            }        };        head.appendChild(script);    }; [/code] You can use it as follows: [code lang="js"]  loadScript("//webserver.com/additional_script.js", function () {    alert('Now the additional script has been loaded.');  }); [/code] Step 2b: Loading jQuery In most cases, you probably want to use jQuery for modifying the host page in-place. There are three possible scenarios: a) the host page does not use jQuery itself; b) the host page does use jQuery and the version works well for you, too; c) the host page does use jQuery but you don't like the particular version of jQuery. The first two cases are easy: you either load jQuery yourself using the method described previously or just use the jQuery provided by the host page. If the host page already uses jQuery but an inconvenient version, you need to load jQuery yourself using jQuery's no conflict option, allowing you to use to jQuerys at the same time in different namespaces: [code lang="js"]  loadScript("//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js", function () {    var $ = $.noConflict();    // now $ is a local variable using your jQuery while the global $ points back to the original jQuery  }); [/code] Step 2c: Loading additional css Loading additional css is very similar to loading additional javascript: [code lang="css"]    var loadStyles = function (url, callback, context) {        var executed = false;        var head = document.getElementsByTagName("head")[0];        var style = document.createElement("link");        style.rel = "stylesheet";        style.href = url;        style.onload = style.onreadystatechange = function() {            if (!executed && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete")) {                executed = true;                style.onload = style.onreadystatechange = null;                if (callback)                    callback.apply(context || this, [url]);            }        };        head.appendChild(style);    }; [/code] You can use it as follows: [code lang="js"]  loadStyles("//webserver.com/styles.css", function () {    alert('Now the additional styles have been loaded.');  }); [/code] Note that in most cases, you don't need to specify a callback function for loading styles, since your javascript code normally doesn't really depend on the actual presence of the styles. Step 2d: Loading additional html Assuming that jQuery is present, you can load additional html as follows: [code lang="js"] var loadHtml = function (url, callback, context) { $.ajax({ url: url, dataType: "html" }).done(function(content) { callback.call(context || this, content, url); }); }; [/code] And use it e.g. as follows: [code lang="js"]  loadHtml("//webserver.com/template.html", function (content) {    $("#where-to-put-the-html").html(content);  }); [/code] Step 3: Creating a bookmarklet setup page All that is left to do is to create a page for folks to install the bookmarklet. It should contain a setup description like this:
  1. Copy the following code to your clipboard: [code lang="html"] javascript:document.body.appendChild(document.createElement(%22script%22)).src%3D%22%2F%2Fwebserver.com%2Fscripts.js%22 [/code]
  2. Bookmark this page.
  3. Edit the bookmark's address and overwrite it by pasting the code you have just copied to your clipboard.
  4. Go to the host website.
  5. Click on the bookmarklet you have just created.
  6. Play around with the demo.
So the next time you want to make an impact potential customers -- sometimes even freak them out (in a good way) -- try Ziggeo’s bookmarklet system.
PREV NEXT