Node.js prototype template, using the GOV.UK Prototype Kit and
the GOV.UK Frontend.
Basically the
GOV.UK Prototype KitandGOV.UK Frontendwrapped up and provided on the Core Delivery Platform
- Requirements
- GOV.UK Prototype Kit and GOV.UK Frontend
- Using the refreshed GOV.UK brand
- Setting a password
- Setting multiple passwords
- Removing the need for a password
- Map and Vector Tiles
- Npm scripts
- Updating dependencies
- Environment Variables and Secrets
- Creating a secret
- Docker
- Licence
Install Node.js >= v22 and npm >= v11. You will find it easier to use
the Node Version Manager nvm
To use the correct version of Node.js for this application, via nvm:
cd nrf-prototypes
nvm useThe GOV.UK Prototype Kit is a tool for building interactive prototypes that look like pages on GOV.UK, it provides components and styles from the GOV.UK Frontend. Both are provided by the Government Digital Service (GDS), this template provides both tools in a wrapper that runs on the Core Delivery Platform at Defra.
Note
The GOV.UK Prototype Kit is built with express.js. The Node.js
applications cdp-node-frontend-template
and cdp-node-backend-template at Defra are built with
Hapi.js
- For information on the
GOV.UK Prototype Kitsee https://prototype-kit.service.gov.uk/docs/ - For tutorials on how to use the
GOV.UK Prototype Kitsee https://prototype-kit.service.gov.uk/docs/tutorials-and-guides - For help with the underlying
GOV.UK Frontendsee:
Warning
The nrf-prototypes is not a production ready application, it is a tool for prototyping. It is not
designed to be used in production or to be resilient, secure or performant, nor should it be. It is designed to be
used for prototyping ideas and testing them with users. It's a great tool for prototyping GOV web applications.
The refreshed GOV.UK brand is available and turned on by default in the nrf-prototypes. To turn it
off simply go to app/config.json and set the "rebrand" property to false. This will turn off
the refreshed brand and use the legacy brand instead.
{
"plugins": {
"govuk-frontend": {
"rebrand": true
}
}
}Caution
Do not commit the .env file to GitHub, it is in the .gitignore file by default. Sensitive information such as a
password can be provided to a prototype via the Secrets page of your prototype in the CDP Portal Frontend
Basic authentication is on by default in CDP environments for prototypes. This means you will need to set a password for your prototype. You can do this via your prototypes secrets tab in the Portal Frontend. For information on how to do this, follow these steps:
- Read the Setting a password section on https://prototype-kit.service.gov.uk/docs/publishing
- Go to the CDP Portal Frontend
- Log in
- Navigate to your prototype on the services list page
- Navigate to your prototypes
Secretstab - Add a secret with a name
PASSWORDand avalueof your choosing - Re-deploy your prototype for the new secrets to be made available to it
The GOV.UK Prototype Kit has the ability to set up multiple passwords via secrets. For more information on how to do
this read the If you want to create additional passwords section on
https://prototype-kit.service.gov.uk/docs/publishing. To add a secret to an environment your prototype is running in
see Creating a secret
By default, the GOV.UK Prototype Kit requires a password has been set on your prototype when it has been deployed to
an environment. If you would like to turn off this requirement you can do so by setting the following environment
variable:
ENV USE_AUTH=falseThis can be set in cdp-app-config for instructions on how to do so
read Environment Variables on CDP.
This prototype includes interactive maps powered by MapLibre GL JS. Vector tiles are served directly from the Node.js application using pre-generated MBTiles files.
Simply start the development server:
npm run devThe app will automatically serve vector tiles from the MBTiles files in tileserver/data/mbtiles/. No separate tileserver is needed.
The map layers use vector tiles (MBTiles format) generated from GeoJSON source files. Pre-generated tiles are committed to the repository, so you typically don't need to regenerate them.
If you need to regenerate tiles from source GeoJSON files:
# Install tippecanoe (one-time setup)
npm run tiles:install
# Convert all GeoJSON layers to MBTiles
npm run tiles:convertThe conversion script processes GeoJSON files from app/assets/map-layers/ and outputs MBTiles to tileserver/data/mbtiles/.
- Vector tiles are stored as MBTiles files (SQLite databases) in
tileserver/data/mbtiles/ - The Express app serves tiles directly via the
/tiles/data/{layer}/{z}/{x}/{y}.pbfendpoint - Tiles are read from MBTiles using
better-sqlite3for fast, efficient access - This approach works identically in development and production, with no external dependencies
nrf-quote-7 uses the same @defra/interactive-map component as the live service. The package is a GOV.UK Prototype Kit plugin, so its scripts and styles are served automatically from /plugin-assets/%40defra%2Finteractive-map/ – nothing is vendored. To upgrade, bump the pinned version in package.json.
- Ordnance Survey basemaps need an
OS_API_KEYin.env(see.env.template). Without one the map offers the keyless Satellite and Streets basemaps. - EDP overlays are served at
/impact-assessor-map/tiles/{layer}/{z}/{x}/{y}.mvt, mirroring production's tile service. They are sliced on demand (no tippecanoe needed) fromapp/lib/map/edp-data.js, which dissolves the nutrient catchments into whole EDP outlines and holds the excluded areas.app/assets/map-layers/edp_excluded_areas.geojsoncontains the River Wensum SAC, The Broads SAC and Broadland Ramsar boundaries from Natural England Open Data (Open Government Licence v3.0). SetIMPACT_ASSESSOR_BASE_URLto proxy the real service instead. - The client code lives in
app/assets/javascripts/interactive-map/and mirrors the production frontend'ssrc/client/javascripts/map/so the two can be diffed.
The content-driven journeys (nrf-quote-7 and nrf-request-to-use-1) have no hidden switches. What a participant types decides the path they take, so a facilitator can steer a session with the email address or the numbers they hand over. Nothing is stored between sessions and no password is ever checked.
Participant details in the footer of every page (next to Clear data) opens a box, styled apart from the service, for the participant's first name, last name and the organisation or client they are acting for. Opening any page with ?participant on the URL (for example /nrf-request-to-use-1/start?participant) shows the same box, so a facilitator can set the details up from a bookmark before the session starts. A blank box keeps the prototype's usual stand-in; "Forget them" clears the details, as Clear data does. They last for the browser session and survive Sign out.
Wherever the request-to-use journey would otherwise make a name up, it uses these instead:
- the name fills in "What's your name?" on the Defra account registration and the Government Gateway's "What is your full name?", is shown on the "Your Defra account" bar, greets the participant in the registration emails and is the full name on "What are your details?" and the certificate
- the organisation or client is the business the participant registers a Defra account for and the company on their emails, and for an agent it is the organisation they act for (the bar under the Prototype banner, "Change organisation")
The details never override a name typed on a page of the journey. The participant details box itself is prototype chrome (app/routes/research.js, app/views/includes/research-participant.html), so nothing about it appears on the screen wall or in screenshots.
Signing in to "Request to use the nature restoration levy" goes through a mock GOV.UK One Login: "Create your GOV.UK One Login" and "Sign in" both lead to the email page, and any password is accepted (the "Sign in with Government Gateway" option goes to the same mock for now). The part of the email address before the @ decides who the participant is:
| Email contains | Account | What they see after signing in |
|---|---|---|
company (e.g. company@test.com) |
Company | Defra account registration first unless invited (see below), then "What is your address?" |
individual |
Individual | Defra account registration first (see below), then "What is your address?" |
anything else (e.g. agent@…) |
Agent | "What are the developer details?", with the organisation bar and Change organisation |
Case does not matter, and the domain is ignored. Sign out (in the header) forgets the account so another email can be tried in the same browser.
Anyone who answers "Yourself, as an individual" to "Who are you requesting to use the nature restoration fund for?" has no Defra account yet, whatever email they sign in with. Anyone who answers "The business or organisation you work for" is taken to be the organisation's account admin and has none either, unless they follow the Employee invitation email link in the footer of the next page instead of Continue: an invited employee has been added to the organisation's account already and skips the registration. For an agent, an email whose local part contains new has no account. Either way, after the One Login password the participant is taken through the Defra ID "register a Defra account" screens before the journey continues:
| Who the levy is for, email | Registration screens | Account afterwards |
|---|---|---|
| an individual, any email | individual (name, telephone, address, memorable word) | Individual |
| an organisation (admin, invitation email not opened), any email | business (trading in the UK, company number, contact details) | Company |
an agent, new@…, new-agent@… |
business | Agent |
The answer to "Are you registering as a business or organisation?" wins over the email: choosing "No, as an individual" always produces an individual, and choosing "Yes" produces a company only when the email contains company, otherwise an agent. Inside the registration:
- any company registration number finds the same fixture business (ACME LTD), and "This is not the right business" goes back to the number
- "No" to having a company registration number skips to the business telephone and email; "No" to being registered to trade in the UK carries on regardless
- any postcode finds the same three addresses; "Enter the address manually" and "My address is not in this list" open a manual address form
- Sign out during registration forgets everything entered so far
- A quote reference must look like
NRL-123456(orNRF-123456). Any reference in that shape retrieves the fixture quote: full planning permission, 100 housing units, a red line boundary inside the Broads and Wensum EDP, and a levy of £25,000 (£250 per unit). A quote made in the quote journey earlier in the same browser session is used instead of the fixture. - Changing the number of units on "Review and amend your quote details" recalculates the levy at £250 per unit. More units than the quote had shows the "levy increased" page; more than 15,000 units shows "not enough capacity".
- "No, delete my quote details" (on the accept levy pages or check your answers) uses the quote journey's delete pages and starts the quote afresh.
- In the quote journey, a red line boundary that does not touch an EDP ends at "no EDP"; 15,001 to 19,999 units ends at the exclusion page and 20,000 or more at "no capacity".
- "Is this a variation?" followed by "Yes" asks whether the original application was committed to the levy, and then for the original reference (same format).
Use the "Turn errors off" link in the footer, next to Clear data, or add ?errors=false to any page of a content-driven journey. Validation is then switched off for the rest of the browser session: every Continue works even with nothing entered or selected. Anything the participant does type is kept; a blank answer is filled in from the journey's sample answers, so later pages still show sensible details (the sample sign-in email is an agent's, so a blank email signs in as an agent). "Turn errors on" in the footer (or ?errors=true) turns validation back on; Clear data resets it too.
A page can list shortcuts for the facilitator under research: in its journey.yaml entry (text and href, one per link). They appear in a "User research" section at the top of the footer, under the crown, and open in a new tab unless the journey says otherwise. On "What would you like to do?" this is the quote email, filled with the sample quote, so a participant can see the NRL reference they will be asked for; the confirmation pages link the email (and the commitment certificate) the submission sends. On "You'll need to create or join a Defra account for your business or organisation" it is the employee invitation email, and opening it changes the path (see "Registering a Defra account first"). Add ?research=false to any page to hide the section for the rest of the browser session (?research=true shows it again; Clear data resets it too). The screen wall's thumbnails, screenshots and the JPG export never show it, but a page opened from the screen wall does.
Add ?preview=1 to any page of a content-driven journey to render it with sample answers (&error=1 shows its error state), or open /tools/journeys/<journey id> for the flow diagram and every screen side by side. The sample answers live under preview in content/<journey id>/journey.yaml; see content/README.md for how the journeys are written.
All available Npm scripts can be seen in package.json To view them in your command line run:
npm runTo update dependencies use npm-check-updates:
The following script is a good start. Check out all the options on the npm-check-updates
ncu --interactive --format groupEnvironment variables and Secrets are used to configure your prototype. Where you set them can be seen in the table below.
| Type | Environment | Where to set them |
|---|---|---|
| Sensitive secrets and Non-sensitive environment variables | local | .env file |
| Sensitive secrets | CDP | CDP Portal Frontend services secrets page |
| Non-sensitive environment variables | CDP | CDP App Config repository by raising a pull request |
Caution
Do not store passwords in GitHub. Sensitive information such as a password can be provided to a prototype via the
secrets page in the CDP Portal Frontend. The .env file is for local development only.
To set environment variables and secrets locally copy the .env.template file to .env and add any
environment variables or secrets your local environment needs.
When your prototype is running on a CDP environment, E.g. dev or ext-test. You can set environment variables via a
GitHub pull request.
To add environment variables read - https://github.com/DEFRA/cdp-documentation/blob/main/how-to/config.md. This will guide you to add non-sensitive environment variables to the https://github.com/DEFRA/cdp-app-config repository via a pull request.
The following environment variables are available in the GOV.UK Prototype Kit. For more information see
their https://prototype-kit.service.gov.uk/docs/ or https://github.com/alphagov/govuk-prototype-kit.
| Name | Value | Description |
|---|---|---|
PASSWORD |
string |
Password for basic authentication |
PASSWORD_KEYS |
string |
Comma-separated list of keys for password authentication |
To add sensitive environment variables know as secrets to your prototype. Add them via your prototypes secrets page on the CDP Portal.
- Go to the CDP Portal Frontend
- Log in
- Navigate to your prototype on the services list page
- Navigate to your prototypes
Secretstab - Add a secret on your chosen environment with a
nameandvalueof your choosing - Re-deploy your prototype for the new secrets to be made available to it
For the most part you will not need to be concerned with docker when running this prototype. Everything is set up and
your docker will automatically be built, published and pushed when you deploy a new version of your prototype via the
UI in the CDP Portal.
Build:
docker build --target development --no-cache --tag nrf-prototypes:development .Run:
docker run -e PORT=3000 -p 3000:3000 nrf-prototypes:developmentBuild:
docker build --no-cache --tag nrf-prototypes .Run:
Update the password field to your password
docker run -e PASSWORD=beepBoopBeep -e PORT=3000 -p 3000:3000 nrf-prototypesTo debug issues in docker and to have a look at the built docker container in the same way as when it runs on CDP. You can run an interactive shell:
Build:
docker build --no-cache --tag nrf-prototypes .Run:
docker run -it --entrypoint /bin/ash nrf-prototypesTHIS INFORMATION IS LICENSED UNDER THE CONDITIONS OF THE OPEN GOVERNMENT LICENCE found at:
http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3
The following attribution statement MUST be cited in your products and applications when using this information.
Contains public sector information licensed under the Open Government license v3
The Open Government Licence (OGL) was developed by the Controller of Her Majesty's Stationery Office (HMSO) to enable information providers in the public sector to license the use and re-use of their information under a common open licence.
It is designed to encourage use and re-use of information freely and flexibly, with only a few conditions.