How to build a GDS website: Part 1

I will be assuming that you’re familiar with the above technologies. So, lets begin!

Most of the places building GDS websites prefer not to use client-side javascript and hence as part of this tutorial, I will be using only server-side technologies such as:

Apart from the official documents (which in my opinion is not good), there are no tutorials out there which properly explain how to setup a GDS website from scratch and continue maintaining it as the code base expands. That’s exactly what i’m going to be doing here.

I’m a Full-Stack developer who has had extensive experience working with various government organisations working on numerous GDS driven applications using technologies like Nunjucks, Node.js, Angular etc.

Create an empty directory and run npm init to initialize your node project. Enter whatever details you prefer for the project and once completed this will create the package.json file within the directory.

Next, we will install all the basic necessary npm packages

npm i govuk-frontend express nunjucks --save

We are installing 3 packages using the above command. govuk-frontend is the official package which contains latest GOV.UK styles, scripts, assets etc.

Create 2 folders on the root of your directory:

  • app — will contain your applications main files like views, controllers, routes etc
  • public — will contain the compiled CSS file

Within the app folder, create assets and views folders:

  • assets — will contain the precompiled sass files
  • views — will contain your main layout.html which will be default layout specific to your application

The locations of these folders depend on your preferences of course but will have to be configured accordingly. I recommend following this structure till you get an understanding of the configurations.

Let’s create our application’s main entry file (starting point when the application is run). Create app.js on the root of your directory.

First, start by importing and configuring nunjucks for your application.

The node_modules/govuk-frontend/ will allow you to reference the govuk/template.njk file from the govuk-frontend package which is needed for us to setup our application’s layout file.

You can read more about the nunjucks configure options here

Additionally, we are also setting the view engine so express knows which template engine to use. Read more about it here.

Next we shall create an application specific layout.html file within the app/views folder which defines how all the pages in your application would look like. All the other HTML files will extend from this layout file. This file in-turn will be extending from the govuk/templates.njk file which we have already made available on the previous step.

You can read more about nunjucks extend here

For now, copy the below code into layout.html. This is taken from the official design-system website. I recommend using the nunjucks variant.

{% block head %}
<!--[if !IE 8]><!-->
<link href="/govuk-frontend/govuk/all.css" rel="stylesheet">
<!--<![endif]-->

{# For Internet Explorer 8, you need to compile specific stylesheet #}
{# see https://frontend.design-system.service.gov.uk/supporting-ie8/#support-internet-explorer-8 #}
<!--[if IE 8]>
<link href="/govuk-frontend/all-ie8.css" rel="stylesheet">
<![endif]-->

{# For older browsers to allow them to recognise HTML5 elements such as `<header>` #}
<!--[if lt IE 9]>
<script src="/html5-shiv/html5shiv.js"></script>
<![endif]-->
{% endblock %}

{% block content %}
<h1 class="govuk-heading-xl">Default page template</h1>
{% endblock %}

{% block bodyEnd %}
{# Run JavaScript at end of the <body>, to avoid blocking the initial render. #}
<script src="/govuk-frontend/all.js"></script>
<script>window.GOVUKFrontend.initAll()</script>
{% endblock %}

We will update this file once we have setup the CSS, JS & other assets.

Create a sass folder under app/assets . Then, create a main.scss file within it. Next, import all the sass rules from GOV.UK frontend package by adding the following to main.scss

@import "node_modules/govuk-frontend/govuk/all";

Now, we need to compile this sass file into a css file as our browser only understands css. I used gulp and gulp-sass to compile the styles but you can make use of other packages like dart-sass as well. My gulpfile looks like:

This will compile and place the css file within the public/css folder.

In your layout.html , replace

<link href="/govuk-frontend/govuk/all.css" rel="stylesheet">

with

<link href="/css/main.css" rel="stylesheet">

Also, you need to make sure express serves assets from public folder. Add the following line to your app.js

app.use(express.static(path.join(__dirname, 'public')))

Now let’s configure express to serve other assets (JS, fonts, images) from the govuk-frontend package. Add the following lines to your app.js

app.use('/assets', express.static(path.join(__dirname, '/node_modules/govuk-frontend/govuk/assets')))

app.use('/govuk-frontend', express.static(path.join(__dirname, '/node_modules/govuk-frontend/govuk')))

The first line makes sure that any requests made to your site for the assets .ie. <site-url>/assets are actually served from govuk-frontend assets. These assets are already being referenced in the govuk css files, you just configured to make sure the css file finds those assets.

The second line is the same but used to serve the JS file we need from govuk-frontend. So, in your layout.html , <script src="/govuk-frontend/all.js"> will be served from node_modules/govuk-frontend/govuk/all.js .

This completes all the govuk-frontend setup.

Now the only thing left is to setup server and routing to make sure that when the desired URL is hit, the correct html page is rendered. Including those code, the complete app.js should now look like

That concludes the entire application setup. Start your application by running

node app.js

Open a browser and navigate to http://localhost:3004/ and voila!

Now that we have a basic GDS website up and running, in the upcoming tutorials we will look towards improving the app by following few coding and structural patterns like moving routing into a separate file to easily manage large number of routes, following a component-based folder structure to better manage large code base etc.