Building a Squarespace integration with Node.js

[av_dropcap1]J[/av_dropcap1]avascript integrations must be built carefully to avoid excessive rendering and network overhead. If well-built, they make it easy to get get complex functionality in a website, without being locked into the vendor (e.g. Squarespace).

I built a small application that uses a search engine to find articles you’ve written for other people, so you can update your writing portfolio if they disappear. This is essentially what you’d do manually to monitor this, and it gives you a list of articles you’ve written. For this article, I’m going to show how to embed this in a Squarespace site.

Here is a sample of the data we want to embed:

squarespace3

Squarespace is a subscription platform for people who want a blog and e-commerce tools, but don’t want the maintenance headaches of WordPress. The templates look pretty nice out of the box:

squarespace2

Squarespace does allow developer customizations but they focus on modifying the look and feel of the site, like changing page templates or CSS. You can customize a site by checking out the template with git, but for non-technical users this is a hassle.

Ideally we want to be able to write a piece of Javascript that can be droped into the page:
squarespace4

[av_dropcap1]W[/av_dropcap1]hile this type of integration has a lot of power, it does break if a browser is configured to block Javascript.

Before we start building something, lets consider an instructive example, the Google Analytics tracking script:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-1570898-2']);
_gaq.push(['_gat._forceSSL']);
_gaq.push(['_trackPageview']);

(function () {
  var ga = document.createElement('script');
  ga.type = 'text/javascript';
  ga.async = true;
  ga.src = 
    ('https:' == document.location.protocol ? 
     'https://ssl' : 'http://www') + 
     '.google-analytics.com/ga.js';
  var s = document.getElementsByTagName('script')[0];
  s.parentNode.insertBefore(ga, s);
})();

Information about your account is set on global variables, then a script block is added to the page, which loads asynchronously. It accesses the script from different domains depending on whether you are on SSL or not. Once loaded, Google Analytics monitors for specific actions, and reports back to the server as operations it tracks occur.

When designing a Javascript integration the least amount of code should live on the page, as it will be nearly impossible to change once people are using it. It may even be valuable to plan on versioning the API.

The backend code we’re going to render is a simple ExpressJS script. I’ve chosen not to add CSS classes, so that this can inherit the styling of the site it is added to:

<ul>
<% for(var i = 0; i < alerts.length; i++) {%>
  <li><%= alerts[i].title %></li>
<% } %>
</ul>

We can then set up a simple Javascript script that can be injected into the page, like so:


We set async and defer to prevent the script from blocking other rendering activities.

To handle SSL and non-ssl pages, I’ve chosen to use a protocol-less URL. This has few downsides1. I haven’t found any documentation on why you’d want to use two domains (SSL and non-SSL) like Google Analytics does, but I suspect that this makes configuring a load balancer easier.

It’s worth noting that older implementations of this type of script used document.write to add the script to the page, which blocked rendering.2

Note that because I put a user ID in the URL, this script won’t be cached across user accounts. There will also be separate copies cached for HTTP and HTTPs.

[av_dropcap1]F[/av_dropcap1]or the backend of this call, we set up a template in Express.js that can add our code to the page:

"use strict";
(function() {
  var template = '