Throughout the examples we will be using:
- node.js for the server;
- On top of node, expres.js framework as a higher-level abstraction;
- mongodb for the persistence layer;
- And borrow some code from o2.js for client-side DOM interaction and event delegation.
But before we start let’s agree on the definitions:
During the article series we will use the terms publisher and widget provider frequently. So it’s important to understand the distinction:
Stateful Widgets vs Stateless Widgets
To have a stateful widget, you will need third-party cookie support; which is one of the many challenges listed below.
Versioning can be a Hassle
You need to define a consistent way to distribute different versions of your code to publishers. So that when you add a new functionality to your existing widget API, it does not break the working code on the publisher sites.
You have to enable different versions of your widget, so that you can introduce major changes in the newer versions of the API, and let publishers gradually upgrade their widgets at their convenience.
You Don’t Own the Execution Environment
When you don’t own the DOM, really careful you should be.
The environment that the widget will run is totally unknown to the widget provider. Worse, the widget provider has almost zero control over that environment.
The execution environment can be a mobile device, a tablet, a power pc, a developer machine, an emulator or simulator, a really old browser… Our widget script has to run equally well in a wide spectrum of doctypes, platforms, and configurations (where some of these configurations can even be overridden by the user).
Moreover the publisher may include your script inside head…/head, or at the middle of body, or just before /body. And the publisher may include the widget script multiple times either intentionally, or by mistake.
Execution Environment is Shared
Not only you don’t own the execution environment, but you also share that environment with guys whom you have no idea where they come from.
Therefore our widget has to do its best to:
- Keep the global namespace clean and be a self-contained piece of code.
- And try to protect itself from badly-written scripts that coexist with it. If not taken proper precautions, these scripts may adversley affect the behavior and performance of our widget.
Passing the Cross Domain Boundary
Since our widget is hosted on an external site, the good old cross domain restrictions apply.
We need to find ways to create a two-way communication channel between the publisher (www.publisher.com) site and the widget provider site (api.mywidget.com). We’ll explore different techniques to accomplish this in the followup articles.
Hack It Like A Thief: Act, but Don’t be Seen
That’s a corollary to the “you don’t own the context” item above.
Since you are a guest, behave like one.
The less our widget changes how provider site works, the better.
And there are several things we can do to decrease the effect of our widget script on the publisher site:
- Use a single namespace;
- Prefix common classes, ids, and attributes;
- Utilize async script includes;
- use lazy loading patterns to delay execution of code that will not be needed immediately.
We’ll come to each and every single one of those items in the followup articles of this series.
Problems With Persisting and Retieving State
In a good old web application, the application state is persisted on the server in the Session object; and genrally “cookies” are used to pass a session ID around to share the session state while browsing different pages.
Since our widget code lives in a different domain than the publisher site, the client may impose restictions on saving cookies as well. By the time of this writing, Safari browser, for instance, disables third party cookies by default.
For our widget to share and persist state information with the widget api server we need to use third party cookies. And since we have no control over the environment our widget script executes (see above), our widget script may be executing in an environment where third-party cookie reading or writing may not be allowed.
There are ways to bypass this restriction too, which we’ll cover in the upcoming articles.
We will explore everything mentioned in this post (and more) in the followup articles.
In the next of the series, we will be preparing our development environment. The interested may get their feet wet by starting to install node.js.
Do you develop external widgets to be distributed to a variety of publisher websites?
I’d love to hear your experiences.
Feel free to share your ideas and suggestions as comments.