Cookies on ons.gov.uk

Cookies are small files stored on your device when you visit a website. We use some essential cookies to make this website work.

We would like to set additional cookies to remember your settings and understand how you use the site. This helps us to improve our services.

You have accepted all additional cookies. You have rejected all additional cookies. You can change your cookie preferences at any time.

Skip to main content

Help users to Correct errors

Overview

Use the correct errors pattern when you need to:

  • make sure that a user has entered something in an input or field
  • check what they have entered is valid

If information is missing or incorrect, advise the user on how to fix it.

Validation should occur after the user submits the form.

When not to use this pattern

Do not use this pattern to tell the user:

  • there is a problem with the service
  • they do not have permission to do something

Instead, use error or status pages.

How to use this pattern

This pattern uses the following components:

If the user tries to submit the form with missing or incorrect information:

  • display the page again and keep the user’s information in the form fields
  • add “Error: ” before the page <title> for screen readers
  • display an error summary at the top of the page that lists all the errors, and move keyboard focus to it
  • show the error details next to each field that has missing or incorrect information

Validation

There are two types of validation:

  • server-side validation
  • client-side validation (in the browser, using either JavaScript or HTML)

Server-side validation

You will always need to carry out server-side validation, even if you use client-side validation. This is because there is no guarantee that client-side validation will work in all circumstances.

For example, the user can bypass client-side validation or JavaScript can fail to load.

Client-side validation

Only add client-side validation if you find a user need for it.

For example, because research shows it helps the user if you validate the information they are providing as they type.

Before you add client-side validation, consider that:

  • it is hard to tell the user about errors in a way that works reliably across different browsers and assistive technologies
  • carrying out both kinds of validation means you have to check their rules do not conflict

Turn off HTML5 validation

HTML5 validation is a type of client-side validation built into browsers. Do not use this as:

  • the visual style, placement and content of HTML5 error messages cannot be made consistent with ONS design principles
  • ONS error messages are more accessible

To turn off HTML5 validation:

Components

Three components are used in this pattern.

Error summary

All the errors on a page are listed in an error summary panel.

This must be displayed at the top of the page’s <main> container and above the <h1> heading. This ensures it is the first element on the page to be read.

The panel contains Accessibility Rich Internet Applications (ARIA) attributes (opens in a new tab)  that ensure that keyboard and screen reader focus is in the correct place.

Example Error Summary contents

Nunjucks
{% from "components/panel/_macro.njk" import onsPanel %}
{% from "components/list/_macro.njk" import onsList %}

{%
    call onsPanel({
        "title": "There are 2 problems with your answer",
        "variant": "error"
    })
%}
    {{
        onsList({
            "element": "ol",
            "itemsList": [
                {
                    "text": "Enter the number of employees paid monthly",
                    "url": "#container-test-number",
                    "variants": "inPageLink"
                },
                {
                    "text": "Enter a number that is less than 101",
                    "url": "#container-test-percent",
                    "variants": "inPageLink"
                }
            ]
        })
    }}
{% endcall %}
HTML
<div aria-labelledby="alert" role="alert" tabindex="-1" class="ons-panel ons-panel--error">
  <div class="ons-panel__header">
    <h2 id="alert" data-qa="error-header" class="ons-panel__title ons-u-fs-r--b">There are 2 problems with your answer
    </h2>
  </div>
  <div class="ons-panel__body">
    <ol class="ons-list">
      <li class="ons-list__item">
        <a href="#container-test-number" class="ons-list__link ons-js-inpagelink">Enter the number of employees paid
          monthly</a>
      </li>
      <li class="ons-list__item">
        <a href="#container-test-percent" class="ons-list__link ons-js-inpagelink">Enter a number that is less than
          101</a>
      </li>
    </ol>
  </div>
</div>

Error summary panel title

To let the user know that there is an error on:

  • question pages, use “there is a problem with your answer”
  • other pages, use “There is a problem with this page”

If there is more than one error on the page, display the number of errors. For example: “There are 2 problems with your answer”.

Error summary panel body

The panel’s body must contain a list of links for each error.

To do this, use the onsList macro, set "element": "ol". If there is only one error, the macro will wrap the link in a <p> instead of the ordered list markup.

Each error link must:

  • describe the specific error and help the user fix it
  • link to the field or fieldset that contains the validation error on the page
  • contain a url key value that matches the id of the panel wrapping the field or fieldset with the error – this needs to start with a hash, for example, #email-input, so Javascript can focus the corresponding input

For guidance on specific error messages, visit the page for each component or pattern.

Error details

Wrap each field that has missing or incorrect information using an error details panel.

This needs to describe the error and help the user fix it.

Example Error Details contents

Nunjucks
{% from "components/input/_macro.njk" import onsInput %}
{{
    onsInput({
        "id": "number-of-employees",
        "type": "number",
        "width": "5",
        "attributes": {
            "min": 0
        },
        "label": {
            "text": "Number of employees paid monthly"
        },
        "error": {
            "id": "number-of-employees-error",
            "text": "Enter the number of employees paid monthly"
        }
    })
}}

{{
    onsInput({
        "id": "percentage-of-employees",
        "type": "number",
        "width": "3",
        "value": "110",
        "label": {
            "text": "Percentage of employees paid monthly"
        },
        "suffix": {
            "title": "per cent",
            "text": "%",
            "id": "employees-percentage-suffix"
        },
        "error": {
            "text": "Enter a number that is less than 101"
        }
    })
}}
HTML
<div class="ons-panel ons-panel--error ons-panel--no-title" id="number-of-employees-error">
  <span class="ons-panel__assistive-text ons-u-vh">Error: </span>
  <div class="ons-panel__body">
    <p class="ons-panel__error">
      <strong>Enter the number of employees paid monthly</strong>
    </p>
    <div class="ons-field">
      <label class="ons-label" for="number-of-employees">Number of employees paid monthly</label>
      <input type="text" id="number-of-employees"
        class="ons-input ons-input--text ons-input-type__input ons-input--error ons-input-number--w-5" pattern="[0-9]*"
        inputmode="numeric" min />
    </div>
  </div>
</div>
<div class="ons-panel ons-panel--error ons-panel--no-title">
  <span class="ons-panel__assistive-text ons-u-vh">Error: </span>
  <div class="ons-panel__body">
    <p class="ons-panel__error">
      <strong>Enter a number that is less than 101</strong>
    </p>
    <div class="ons-field">
      <label class="ons-label" for="percentage-of-employees">Percentage of employees paid monthly</label>
      <span class="ons-input-type ons-js-input-container-abbr">
        <span class="ons-input-type__inner">
          <input type="text" id="percentage-of-employees"
            class="ons-input ons-input--text ons-input-type__input ons-input--error ons-input-number--w-3"
            aria-labelledby="percentage-of-employees employees-percentage-suffix" value="110" pattern="[0-9]*"
            inputmode="numeric" />
          <abbr id="employees-percentage-suffix" class="ons-input-type__type ons-js-input-abbr" aria-label="per cent"
            role="figure" title="per cent">%</abbr>
        </span>
      </span>
    </div>
  </div>
</div>

The error component is called within each component by providing a text and id value within the error object.

The text string for the error details panel must be the same as its corresponding link in the error summary panel.

Guidance on specific error messages can be found on the page for each form component.

Example

The prototype provides an example of form validation for inputs that have missing or incorrect information.

Attempt to submit the form as it is to see the error validation in action.

Important information:

The form in the example prototype will always fail validation.

To see examples of how you should correct user errors, view the correct errors example prototype (opens in a new tab) .

Help improve this page

Let us know how we could improve this page, or share your user research findings. Discuss the ‘Correct errors’ pattern on GitHub (opens in a new tab)