Skip to main content
Warning This document has not been updated for a while now. It may be out of date.
Last updated: 21 Oct 2020

whitehall: Whitehall JavaScript

Should be read in conjunction with the GDS Way JS styleguide

File structure and namespacing

Each JavaScript object should be stored in its own file with a filename reflecting the object name. In the spirit of keeping things similar to the CSS, they should be stored in:


Views are view-specific scripts and as with the css, their file path and name should exactly mirror the view template or partial it applies to. The name of the script object should reflect the whole view path (the object in /admin/editions/index.js should be called GOVUK.adminEditionsIndex).

Modules are re-useable things. An example of a module would be the script for a tabbed content block. Modules should not be initialised globally, and should only be initialised when needed, by the layout / partial which needs it (see script initialisation). If a script is only ever going to be used in one place, don't make it a module.

Helpers are scripts which are loaded everywhere (such as the script which prevents forms from being submitted twice).

Namespaces should be kept simple and all constructors should be under GOVUK. The JavaScript layer is thin for whitehall and so (at least at present) there's no need to use deeper namespaces.

Script initialisation

Scripts should be initialised with GOVUK.init:

GOVUK.init(GOVUK.SomeScript, { el: '.js-the-thing' })

If the passed in object is a constructor, GOVUK.init creates an instance of the passed in constructor, passing the second argument through as an argument. A reference to the new instance is stored in GOVUK.instances.

Otherwise, GOVUK.init will call init on the passed in hash, treating it as a singleton.

Scripts should only be initialised when needed and should make use of the rails helper initialise_script:

<% initialise_script "GOVUK.SomeView", el: '.js-some-view' %>

This rails helper takes a ruby hash as a second argument, which is jsonified and passed down to the javascript constructor (in content_for block :javascript_initialisers). This is not done in $.ready by default, so if the script needs to wait for $.ready, it should do so itself.

This initialise_script line should be in the most appropriate template/partial for view scripts / view-specific helpers, and should be near the :javascript_initialisers yield in the applicable layout for site-wide helpers.