The London Node User group website is a static site hosted on github pages, it renders at build time, in the browser and works offline using Speclate.

The idea behind Speclate is you have a single file (a spec) which defines how your routes, pages and components fit together. A spec can be used to generate a static site and lots more too.  With the help of speclate-router we generate a router which swaps out the appropriate HTML elements to transition nicely between pages.

Let’s look at a simple example:

module.exports = {
     '/': {
         page: 'home',
         selectors: {
             title: 'Home',
             'a.home': {
                 className: 'active'
     '/contact.html': {
         page: 'contact',
         selectors: {
             title: 'Contact',
             'a.contact': {
                 className: 'active'

This spec will produce index.html and contact.html based on the contents of /pages/home/home.html and /pages/contact/contact.html and the values in the selectors object.

At the moment Speclate relies on a couple of conventions. /pages/layout.html needs to contain an element with an id of “container”for the pages to be appended to. This will move to config eventually.

I’ve created a simple example app. You can see the demo running on Netlify, and get the source code on GitHub. You can also read more about the spec format in the speclate readme.


Underneath the hood Speclate uses Sizlate which makes extensive use of Sizzle, the selector engine from jQuery.  On the server, Cheerio provides a fast DOM implementation for generating the markup.

Rendering can be broken down into three steps. Firstly we replace the main page (using #container), then we apply the page spec, this will apply selectors and components to the page and lastly we apply the global selectors to the markup. This allows us to effect elements in the main layout such as the page title.

In the example there are three commands in the package.json to generate the site:

"scripts": {
    "markup": "speclate",
    "client": "browserify ./client/router.js > ./client/router-compiled.js",
    "build": "npm run client && npm run markup"

‘npm run markup’ will generate a functional HTML site. ‘npm run client’ uses browserify to generate the client-side router and ‘npm run build’ generates the whole site by running both commands.


Currently, the LNUG website works offline using an AppCache.manifest file. That file is generated from the spec like so:

speclate.site.appCache(spec, [

We use appCache Nanny to handle updates but the experience is still not great. The latest releases of Speclate now use the fetch API so it opens up lots of possibilities with Service Workers.


EnhanceConf Scholarship


One of the big motivations behind EnhanceConf  was education. Conferences are a great place to learn but the associated costs often make them difficult for many to attend. In the spirit of progressive enhancement, we want to make EnhanceConf available to the widest possible audience.

We have allocated a number of scholarship tickets for people who would like to attend but cannot pay for a ticket.

How to Apply

Send a short email to info@enhanceconf.com with a title of EnhanceConf Scholarship.

In your email please include:

– Who are you?
– What do you do?
– Why would you like the scholarship?

Who should apply:

The scholarships are available to anyone not normally able to attend a conference. If that might be you (even if you’re not in one of the groups below) then please apply.

Some of the groups we are especially keen to support include:

  • Ethnic minorities
  • Women
  • Disabled people
  • Charity workers
  • Education / students
  • Open source projects
  • Industry newcomers

If you have any questions, just send an email to info@enhanceconf.com


All emails will be treated in the strictest confidence, we will not announce who the scholarships go to but you’re welcome to say so yourself.

Successful applicants will get a standard conference ticket.

We are only able to cover the cost of the conference ticket so please consider your travel costs before applying.

EnhanceConf line-up

Over the last 6 months, with the help of some trusted advisors, I’ve been putting together the line-up for EnhanceConf.

The whole event is dedicated to progressive enhancement, but what does that even mean in 2016? Well, that’s the point of EnhanceConf. We get to spend the 4th of March in The Great Room figuring it out.


We are going to start the day thinking about why we do progressive enhancement. Nat Buckley will look at many of the assumptions we make in modern web development. Anna Debenham will then look at some of the unusual devices people use to interact with our sites/apps. Stefan Tilkov will provide an architect’s perspective.

In the second section, we are going to look at some real world examples. We’ve got Ola Gasidlo from Styla/Hoodie and Oliver Joseph Ash from the Guardian talking about their experiences making things work offline. Forbes Lindesay will be talking about building apps that can render on the server and in the browser.

After lunch, we are going to think a bit more about design and UX. Does progressive enhancement constrain design? Phil Hawksworth and Stephen Waller will debate. Jen Simmons will explain why 2016 will be the year that web layouts change and how to use these new techniques as an enhancement. Adam Silver will talk about embracing simplicity.

In the final section, we are going to look to the future. How can we build interfaces given how little we know about the people and devices using them? Robin Christopherson will be talking about inclusive design. Stephanie Morillo will talk about copy and what to think about when writing it. Aaron Gustafson will round off the event by talking about building for devices that don’t exist yet.

After each section, we are going to have 20 minutes of Q&A run by Jeremy Keith.

As if that wasn’t enough, the Planning Adaptive Interfaces workshop provides a unique opportunity to get training from Aaron Gustafson while he’s in London. We are giving a limited number of copies of Aaron’s e-book Adaptive Web Design with combined conference and workshop tickets.

Reserve your seat

Building on the Web


When building a house the foundations are fundamental to it’s structural integrity. Without good strong foundations the house is weak and liable to fall over at any moment.

Things on the web also have foundations in the form of HTML and URIs.  JavaScript can then be layered on top to improve the experience. It’s called progressive enhancement and people seem to be forgetting about it these days.

It’s pretty simple, build your HTML and CSS  first and then override the default behaviours with JavaScript.  This will ensure you are building on solid foundations.

When generating HTML on the server, you can easily re-use it with JavaScript. Its far better than generating the HTML in the browser (with JavaScript) and either ignoring Search engines or having to duplicate your logic on the server for SEO, accessibility and things like RSS feeds.

Here are some rather sweeping statements:

1. JavaScript should NEVER be used to process data in the browser.

2. JavaScript should rarely be used in the browser to generate html (sharing code with server-side JavaScript is acceptable).

I did warn you they were rather sweeping.

I’ve heard it said that if you want to provide an app/flash like experience you need to use JavaScript to render your pages: You need to build single page JavaScript apps.

history.pushState() tells us otherwise. You can read about it here.

Basically it makes it possible for what we now call single page web apps to exist across multiple pages while still providing nice page transitions (no page refresh).

history.pushState() – A Fallback

History.pushState is all well and good but it’s only available in WebKit and Firefox(4) at the moment.  Maybe that is why people are seeing hashbangs as an alternative solution. Personally I would rather fallback to a fragment identifier (#) only in situations where history.pushState is not available.

There would need to be a bit of JavaScript at the top of each page redirecting users to the appropriate fragment identifier in browsers that do not support pushState.

So when pushState is not available:


might redirect to :


which would then go and fetch the contents from


If a page is loaded with the fragment identifier in a browser that supports pushState the hash should be removed and pushState used.


When you require JavaScript for templating and data processing you are on a very slippery slope to writing JavaScript applications.

We have for a long time been able to obfuscate our data with technologies like Flash, I for one have avoided these technologies because I believe that when we publish data properly on the web it becomes more re-usable, findable, accessible and actually has far greater potential.

By all means use JavaScript, but please don’t rely on it.