Five tips from five weeks using the GOV.UK prototyping kit

Photo by rawpixel on Unsplash

For the past five weeks I’ve been working on a digital project in the public sector, as part of an amazing agile team conforming to a Government Digital Service (GDS) approach to the “digital transformation of government”. As the UX/Interaction Designer on the project, one of my primary outputs is a continually iterated, interactive prototype, built using the GOV.UK Prototyping Kit. The publicly available prototyping kit is accompanied by guidelines to the relevant styles, components and patterns, supported by wider resources such as a Slack community and wiki of suggestions, pattern discussions, etc., collectively known as the GOV.UK Design System.

The prototyping kit is built on the Nunjucks templating framework, which is “heavily inspired” by the Jinja2 templating language, which ultimately runs on top of the Express JS web framework. I’m relatively good with front-end technologies — HTML5, SASS, gulp, some experience of JS frameworks, etc — but despite the helpful resources supporting the prototyping kit I found myself having to work harder than I’d have liked to understand the Nunjucks way of doing things. Beyond straightforward HTML prototyping, I often found myself wanting to implement a well-documented Jinja2 or Express method, only to find it doesn’t quite work the same in Nunjucks. Some of this undoubtedly needed a mindset shift on my part — recognising the benefits of working to the constraints of a prototyping kit that very effectively balances the need to design and test vastly different services with a shared design language and (usually) delivery platform — but nonetheless a few key things I learnt along the way feel like things worth sharing. In appreciation of the open, sharing approach I’ve found to surround the GOV.UK Design System community, here are my five tips from five weeks working with the GOV.UK prototyping kit.

Note: As the project is still very much active — and only in it’s Alpha phase — I’ve generalised my five tips and restrained from using any screenshots.

1. Create a prototype launch page

Modern UX design within an agile methodology revolves around informed design decisioning, user testing, analysing and iterating. The prototyping kit perfectly supports this approach but I quickly found we needed a launch page to anchor the alternative prototype versions (and their archived snapshots) along with any key design resources. I’m sure this is standard practice for most designers working in this way — but planning for it from the outset impacts other structural and logic decisions later so it’s worth specific consideration from the outset. For instance, each of our distinct product directions is referred to as Service Model A, Service Model, B, etc. The design and prototype of each service model is iterated frequently and used extensively in user research. The whole prototype codebase is stored in Github and hosted on Heroku, with regular snapshots archived for easily accessing and browsing previous iterations (currently this is on an adhoc basis but conceivably could be tied more explicitly into an incremental user research plan). To minimise code and to ensure backwards stability of the snapshots whilst continually enhancing the latest version of each service model, it’s crucial to adopt a consistent URL structure. My approach is:

  • domain/a/index.html (Service Model A latest)
  • domain/a/181105/index.html (Service Model A snapshot)
  • domain/b/index.html (Service Model B latest)

Additionally, I have been pleasantly surprised at the impact the prototype launch page has had in acting as both a “shop window” and a visible, interactive status of our progress. From the early visualisation of ideas through to convincingly representing the end product, as designers we are often the lucky ones who get to materialise the efforts of many people.

2. A better route forward

From the Nunjucks documentation and through discussion with other designers experienced in using the GOV.UK prototyping kit, it was apparent to me quite early in the prototyping that whilst the GOV.UK Design System is great for building page templates, understanding routing is crucial for effectively producing smart prototypes. I initially used routing for ‘simply’ adding some rules to the page flows and, perhaps because I’m so familiar using PHP to do web stuff, I kept trying to force too much logic into my Nunjucks templates. However, once I focussed my Nunjucks templates on handling purely presentational logic and moved any application logic into the routing, the separation quickly made more sense and I found myself spending more and more time in the routes.js file. However, referring back to our prototype launch page with a URL structure supporting multiple versions and snapshots, it soon became obvious that static routing wouldn’t get me very far. With a bit of trial and error, and a little help from the Express documentation and a few (though not many) Stackoverflow threads, I arrived at a dynamic regex routing pattern that is flexible and robust, and now acts as the backbone to my prototype application logic. Each page route basically uses the following pattern:

3. Find a balance between moving forwards and maintaining backwards

So now my launch page enables access to all the prototype versions and my super dynamic routing provides a flexible but powerful means of adding suitably separated logic. But guess what? Inevitably things still break. I need to push forward as quickly as possible with the latest Service Model without spending too much time fixing prototypes for broken previous models. The best way I found to handle this is to plan for it from the start (what ‘proper’ professional developers might call “defensive programming”) by assuming that any piece of data might possibly be unavailable. I found this also happened frequently in deep-linking scenarios where I built the prototype to be relatively sequential — building data as required to mimic the final system — but frequently being asked to send someone a link to a specific page.

To handle this, I found it fairly effective to always build the prototype first using default fallback data, and then iteratively enhance it using routing logic and/or session data. I split fallback data into two types: global and page. My global fallback data lives in _globals.html and is essentially just a bunch of data defaults preconfigured as JS objects, typically representing key phrases, dates, etc that might need to be easily updated across the whole prototype. Subsequently, in specific Nunjucks page templates, I typically start with inline page fallback data and then override it rather than replace it. Nunjucks (and JS) has some nice approaches to support this, such as:

{% set full_name = data.applicant.full_name or globals.applicant.full_name or "John Smith" %}
Hi there {{ full_name | title }}

It’s a bit more verbose but overall it helps to hide data dependent issues whilst sometimes also providing clarity when trying to understand at a glance what data might be expected within a template.

Obviously there are wider errors that can (and do) occur as prototypes change and progress, but mostly I’ve found that using dynamic routing and fallback data catch the majority of them.

4. Posting stuff is mostly better than getting it

Considering the two obvious route methods for moving between pages in my prototype e.g. get and post, for quite a while I persisted with trying to use both interchangeably. However, as my prototypes increased in complexity, I switched almost entirely to only using post. In some cases I was using get because I only needed a very basic link between pages but quite often I was trying to make get do stuff that post does automatically (in terms of passing data around easily).

Using forms in page templates to consistently use post required me to utilise two HTML/CSS tricks quite frequently. Firstly, it quickly became apparent that I would need a means of posting from a form with a link — something not supported by default in HTML. The trick here is to use an HTML button that is stripped of it’s button appearance, resulting in it looking like a link, the SASS for which is:

button.button-as-link {
   background: none !important;
color: #005ea5;
border: none;
padding: 0 !important;
font: inherit;
cursor: pointer;
text-decoration: underline;
   &:hover { color: #2b8cc4; }
}

Secondly, I then had a ‘groan’ moment when I realised that I’d have to find a hacky way of overriding the form action so that different links or buttons within a form could link to different URLs. Except, as it happens, it’s not hacky. HTML has got it covered. Any submit button by default uses the action attribute defined on the form but it can be overridden by adding an attribute to the button itself:

<button type="submit" class="button-as-link" formaction="post-to-this-url">I'm going somewhere different</button>

Note: It could be observed that adopting post and therefore using a form where it may not be essential conflicts with Tip 5 in that it leads to prototype pages which could be built differently to better represent the final production code. However, I would argue that, within reason, the outcome of creating more robust and smarter prototype pages results in a better informed solution anyway.

5. Strive for a prototype that informs the production build

Towards the start of a project, prototyping activity is very focussed on visualising early ideas, supporting user research testing and iterating the product towards a solution. However, as my prototype progressed, I found it helpful to increasingly consider how the prototype could inform the production build. That’s not to say this should happen at the end of the prototyping stage — the earlier the better — but often there isn’t enough technical definition at the start to usefully inform the prototype anyway. I can’t yet vouch for the effectiveness of this prototype in informing the production build because we’re only midway through the Alpha phase, but the more closely I have attempted to understand and reflect the build requirements the stronger I think the prototype is, both in informing the design of the product and subsequently as a reference for the production build.

As UX or interaction designers we are obviously expected to liaise with developers to ensure our design is technically deliverable, but the GOV.UK Design System goes further by establishing a set of components and patterns that should be used in both the prototype and the production environment. One extra consideration here is whether to write prototype page templates using HTML or Nunjucks macros. In the GOV.UK Design System, a snippet for each component is provided in both HTML and Nunjucks macro format. I initially used the Nunjucks macros as I liked their brevity and that the consistency of output would be handled for me by the macro. However, as the prototype progressed I found that the macros didn’t always expose the flexibility that I needed and subsequently I didn’t like the inconsistency of using Nunjucks macros in some places and HTML in others. Therefore, for consistency of documentation and when handing the templates over to developers, I decided to revert to using HTML snippets throughout the prototype.


In my relatively short time using it, despite a few Nunjucks quirks, I have found the GOV.UK Prototyping Kit to be an excellent package, assisting me in iteratively designing the product whilst simultaneously representing and specifying the outcome. I’m sure there are more essential tricks and tips I’ll learn as I develop my use of the kit on this and hopefully other GDS projects in future. In the meantime, whether you’ve never used the Prototyping Kit or are an established user (it’s currently on version 7!), by all means use the comments to ask questions, provide corrections or add links to further resources.