Error summary
Include an error summary at the top of a page to summarise any mistakes a user has made.
<div class="hs2-error-summary" aria-labelledby="error-summary-title" role="alert" tabindex="-1">
<h2 class="hs2-error-summary__title" id="error-summary-title">
There is a problem
</h2>
<div class="hs2-error-summary__body">
<p>
Describe the errors and how to correct them
</p>
<ul class="hs2-list hs2-error-summary__list">
<li>
<a href="#example-error-1">Date of birth must be in the past</a>
</li>
</ul>
</div>
</div>
Nunjucks macro options
Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
Some options are required for the macro to work; these are marked as "Required" in the option description.
If you're using Nunjucks macros in production with "html" options, or ones ending with "html", you must sanitise the HTML to protect against cross-site scripting exploits.
Name | Type | Required | Description |
---|---|---|---|
Name titleText | Type string | Required true | Description If `titleHtml` is set, this is not required. Text to use for the heading of the error summary block. If `titleHtml` is provided, `titleText` will be ignored. |
Name titleHtml | Type string | Required true | Description If `titleText` is set, this is not required. HTML to use for the heading of the error summary block. If `titleHtml` is provided, `titleText` will be ignored. |
Name descriptionText | Type string | Required false | Description Text to use for the description of the errors. If you set `descriptionHtml`, the component will ignore `descriptionText`. |
Name descriptionHtml | Type string | Required false | Description HTML to use for the description of the errors. If you set this option, the component will ignore `descriptionText`. |
Name errorList | Type array | Required true | Description Contains an array of error link items and all their available arguments. |
Name errorList[].href | Type string | Required false | Description Href attribute for the error link item. If provided item will be an anchor. |
Name errorList[].text | Type string | Required true | Description If `html` is set, this is not required. Text for the error link item. If `html` is provided, the `text` argument will be ignored. |
Name errorList[].html | Type string | Required true | Description If `text` is set, this is not required. HTML for the error link item. If `html` is provided, the `text` argument will be ignored. |
Name errorList[].attributes | Type object | Required false | Description HTML attributes (for example data attributes) to add to the error link anchor. |
Name classes | Type string | Required false | Description Classes to add to the error-summary container. |
Name attributes | Type object | Required false | Description HTML attributes (for example data attributes) to add to the error-summary container. |
{% from 'error-summary/macro.njk' import errorSummary %}
{{ errorSummary({
"titleText": "There is a problem",
"descriptionText": "Describe the errors and how to correct them",
"errorList": [
{
"text": "Date of birth must be in the past",
"href": "#example-error-1"
}
]
}) }}
When to use an error summary
When a user makes a mistake, you must show an error summary at the top of the page as well as an error message next to each answer that contains an error.
Always show an error summary when there is a validation error, even if there’s only 1 mistake.
How to use an error summary
You must:
- add "Error: " to the beginning of the
<title>
so screen readers read it out as soon as possible - show an error summary at the top of a page
- move the keyboard focus to the error summary
- include the heading "There is a problem"
- link to each of the answers that have validation errors
- show the same error messages next to the inputs with errors
Follow GOV.UK Design System guidance on writing good error messages.
Linking from the error summary to each answer
You must link the errors in the error summary to the answer they relate to.
For questions that require a user to answer using a single field, like a select, textarea or text input, link to the field.
<div class="hs2-error-summary" aria-labelledby="error-summary-title" role="alert" tabindex="-1">
<h2 class="hs2-error-summary__title" id="error-summary-title">
There is a problem
</h2>
<div class="hs2-error-summary__body">
<ul class="hs2-list hs2-error-summary__list">
<li>
<a href="#name">Enter your full name</a>
</li>
</ul>
</div>
</div>
<h1 class="hs2-heading-l">Your details</h1>
<div class="hs2-form-group hs2-form-group--error">
<label class="hs2-label" for="name">
Full name
</label>
<span class="hs2-error-message" id="name-error">
<span class="hs2-u-visually-hidden">Error:</span> Enter your full name
</span>
<input class="hs2-input hs2-input--error" id="name" name="name" type="text" aria-describedby="name-error">
</div>
Nunjucks macro options
Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
Some options are required for the macro to work; these are marked as "Required" in the option description.
If you're using Nunjucks macros in production with "html" options, or ones ending with "html", you must sanitise the HTML to protect against cross-site scripting exploits.
Name | Type | Required | Description |
---|---|---|---|
Name titleText | Type string | Required true | Description If `titleHtml` is set, this is not required. Text to use for the heading of the error summary block. If `titleHtml` is provided, `titleText` will be ignored. |
Name titleHtml | Type string | Required true | Description If `titleText` is set, this is not required. HTML to use for the heading of the error summary block. If `titleHtml` is provided, `titleText` will be ignored. |
Name descriptionText | Type string | Required false | Description Text to use for the description of the errors. If you set `descriptionHtml`, the component will ignore `descriptionText`. |
Name descriptionHtml | Type string | Required false | Description HTML to use for the description of the errors. If you set this option, the component will ignore `descriptionText`. |
Name errorList | Type array | Required true | Description Contains an array of error link items and all their available arguments. |
Name errorList[].href | Type string | Required false | Description Href attribute for the error link item. If provided item will be an anchor. |
Name errorList[].text | Type string | Required true | Description If `html` is set, this is not required. Text for the error link item. If `html` is provided, the `text` argument will be ignored. |
Name errorList[].html | Type string | Required true | Description If `text` is set, this is not required. HTML for the error link item. If `html` is provided, the `text` argument will be ignored. |
Name errorList[].attributes | Type object | Required false | Description HTML attributes (for example data attributes) to add to the error link anchor. |
Name classes | Type string | Required false | Description Classes to add to the error-summary container. |
Name attributes | Type object | Required false | Description HTML attributes (for example data attributes) to add to the error-summary container. |
{% from 'error-summary/macro.njk' import errorSummary %}
{% from 'input/macro.njk' import input %}
{{ errorSummary({
"titleText": "There is a problem",
"errorList": [
{
"text": "Enter your full name",
"href": "#name"
}
]
}) }}
<h1 class="hs2-heading-l">Your details</h1>
{{ input({
"label": {
"text": "Full name"
},
"id": "name",
"name": "name",
"errorMessage": {
"text": "Enter your full name"
}
}) }}
When a user has to enter their answer into multiple fields, such as the day, month and year fields in the date input component, link to the 1st field that contains an error.
If you do not know which field contains an error, link to the 1st field.
<div class="hs2-error-summary" aria-labelledby="error-summary-title" role="alert" tabindex="-1">
<h2 class="hs2-error-summary__title" id="error-summary-title">
There is a problem
</h2>
<div class="hs2-error-summary__body">
<ul class="hs2-list hs2-error-summary__list">
<li>
<a href="#dob-errors-year">Date of birth must include a year</a>
</li>
</ul>
</div>
</div>
<div class="hs2-form-group hs2-form-group--error">
<fieldset class="hs2-fieldset" aria-describedby="dob-errors-hint dob-errors-error" role="group">
<legend class="hs2-fieldset__legend hs2-fieldset__legend--l">
<h1 class="hs2-fieldset__heading">
What is your date of birth?
</h1>
</legend>
<div class="hs2-hint" id="dob-errors-hint">
For example, 15 3 1984
</div>
<span class="hs2-error-message" id="dob-errors-error">
<span class="hs2-u-visually-hidden">Error:</span> Date of birth must include a year
</span>
<div class="hs2-date-input" id="dob-errors">
<div class="hs2-date-input__item">
<div class="hs2-form-group">
<label class="hs2-label hs2-date-input__label" for="dob-errors-day">
Day
</label>
<input class="hs2-input hs2-date-input__input hs2-input--width-2" id="dob-errors-day" name="day" type="text" value="15" pattern="[0-9]*" inputmode="numeric">
</div>
</div>
<div class="hs2-date-input__item">
<div class="hs2-form-group">
<label class="hs2-label hs2-date-input__label" for="dob-errors-month">
Month
</label>
<input class="hs2-input hs2-date-input__input hs2-input--width-2" id="dob-errors-month" name="month" type="text" value="3" pattern="[0-9]*" inputmode="numeric">
</div>
</div>
<div class="hs2-date-input__item">
<div class="hs2-form-group">
<label class="hs2-label hs2-date-input__label" for="dob-errors-year">
Year
</label>
<input class="hs2-input hs2-date-input__input hs2-input--width-4 hs2-input--error" id="dob-errors-year" name="year" type="text" pattern="[0-9]*" inputmode="numeric">
</div>
</div>
</div>
</fieldset>
</div>
Nunjucks macro options
Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
Some options are required for the macro to work; these are marked as "Required" in the option description.
If you're using Nunjucks macros in production with "html" options, or ones ending with "html", you must sanitise the HTML to protect against cross-site scripting exploits.
Name | Type | Required | Description |
---|---|---|---|
Name titleText | Type string | Required true | Description If `titleHtml` is set, this is not required. Text to use for the heading of the error summary block. If `titleHtml` is provided, `titleText` will be ignored. |
Name titleHtml | Type string | Required true | Description If `titleText` is set, this is not required. HTML to use for the heading of the error summary block. If `titleHtml` is provided, `titleText` will be ignored. |
Name descriptionText | Type string | Required false | Description Text to use for the description of the errors. If you set `descriptionHtml`, the component will ignore `descriptionText`. |
Name descriptionHtml | Type string | Required false | Description HTML to use for the description of the errors. If you set this option, the component will ignore `descriptionText`. |
Name errorList | Type array | Required true | Description Contains an array of error link items and all their available arguments. |
Name errorList[].href | Type string | Required false | Description Href attribute for the error link item. If provided item will be an anchor. |
Name errorList[].text | Type string | Required true | Description If `html` is set, this is not required. Text for the error link item. If `html` is provided, the `text` argument will be ignored. |
Name errorList[].html | Type string | Required true | Description If `text` is set, this is not required. HTML for the error link item. If `html` is provided, the `text` argument will be ignored. |
Name errorList[].attributes | Type object | Required false | Description HTML attributes (for example data attributes) to add to the error link anchor. |
Name classes | Type string | Required false | Description Classes to add to the error-summary container. |
Name attributes | Type object | Required false | Description HTML attributes (for example data attributes) to add to the error-summary container. |
{% from 'error-summary/macro.njk' import errorSummary %}
{% from 'date-input/macro.njk' import dateInput %}
{{ errorSummary({
"titleText": "There is a problem",
"errorList": [
{
"text": "Date of birth must include a year",
"href": "#dob-errors-year"
}
]
}) }}
{{ dateInput({
"id": "dob-errors",
"fieldset": {
"legend": {
"text": "What is your date of birth?",
"classes": "hs2-fieldset__legend--l",
"isPageHeading": true
}
},
"hint": {
"text": "For example, 15 3 1984"
},
"errorMessage": {
"text": "Date of birth must include a year"
},
"items": [
{
"name": "day",
"classes": "hs2-input--width-2",
value: 15
},
{
"name": "month",
"classes": "hs2-input--width-2",
value: 3
},
{
"name": "year",
"classes": "hs2-input--width-4 hs2-input--error"
}
]
}) }}
For questions that require a user to select one or more options from a list using radios or checkboxes, link to the 1st radio or checkbox.
<div class="hs2-error-summary" aria-labelledby="error-summary-title" role="alert" tabindex="-1">
<h2 class="hs2-error-summary__title" id="error-summary-title">
There is a problem
</h2>
<div class="hs2-error-summary__body">
<ul class="hs2-list hs2-error-summary__list">
<li>
<a href="#contact">Select how you like to be contacted</a>
</li>
</ul>
</div>
</div>
<div class="hs2-form-group hs2-form-group--error">
<fieldset class="hs2-fieldset" aria-describedby="contact-hint contact-error">
<legend class="hs2-fieldset__legend hs2-fieldset__legend--l">
<h1 class="hs2-fieldset__heading">
How would you like to be contacted?
</h1>
</legend>
<div class="hs2-hint" id="contact-hint">
Select all options that are relevant to you.
</div>
<span class="hs2-error-message" id="contact-error">
<span class="hs2-u-visually-hidden">Error:</span> Select how you like to be contacted
</span>
<div class="hs2-checkboxes">
<div class="hs2-checkboxes__item">
<input class="hs2-checkboxes__input" id="contact" name="contact" type="checkbox" value="email">
<label class="hs2-label hs2-checkboxes__label" for="contact">
Email
</label>
</div>
<div class="hs2-checkboxes__item">
<input class="hs2-checkboxes__input" id="contact-2" name="contact" type="checkbox" value="phone">
<label class="hs2-label hs2-checkboxes__label" for="contact-2">
Phone
</label>
</div>
<div class="hs2-checkboxes__item">
<input class="hs2-checkboxes__input" id="contact-3" name="contact" type="checkbox" value="text message">
<label class="hs2-label hs2-checkboxes__label" for="contact-3">
Text message
</label>
</div>
</div>
</fieldset>
</div>
Nunjucks macro options
Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
Some options are required for the macro to work; these are marked as "Required" in the option description.
If you're using Nunjucks macros in production with "html" options, or ones ending with "html", you must sanitise the HTML to protect against cross-site scripting exploits.
Name | Type | Required | Description |
---|---|---|---|
Name titleText | Type string | Required true | Description If `titleHtml` is set, this is not required. Text to use for the heading of the error summary block. If `titleHtml` is provided, `titleText` will be ignored. |
Name titleHtml | Type string | Required true | Description If `titleText` is set, this is not required. HTML to use for the heading of the error summary block. If `titleHtml` is provided, `titleText` will be ignored. |
Name descriptionText | Type string | Required false | Description Text to use for the description of the errors. If you set `descriptionHtml`, the component will ignore `descriptionText`. |
Name descriptionHtml | Type string | Required false | Description HTML to use for the description of the errors. If you set this option, the component will ignore `descriptionText`. |
Name errorList | Type array | Required true | Description Contains an array of error link items and all their available arguments. |
Name errorList[].href | Type string | Required false | Description Href attribute for the error link item. If provided item will be an anchor. |
Name errorList[].text | Type string | Required true | Description If `html` is set, this is not required. Text for the error link item. If `html` is provided, the `text` argument will be ignored. |
Name errorList[].html | Type string | Required true | Description If `text` is set, this is not required. HTML for the error link item. If `html` is provided, the `text` argument will be ignored. |
Name errorList[].attributes | Type object | Required false | Description HTML attributes (for example data attributes) to add to the error link anchor. |
Name classes | Type string | Required false | Description Classes to add to the error-summary container. |
Name attributes | Type object | Required false | Description HTML attributes (for example data attributes) to add to the error-summary container. |
{% from 'error-summary/macro.njk' import errorSummary %}
{% from 'checkboxes/macro.njk' import checkboxes %}
{{ errorSummary({
"titleText": "There is a problem",
"errorList": [
{
"text": "Select how you like to be contacted",
"href": "#contact"
}
]
}) }}
{{ checkboxes({
"idPrefix": "contact",
"name": "contact",
"fieldset": {
"legend": {
"text": "How would you like to be contacted?",
"classes": "hs2-fieldset__legend--l",
isPageHeading: true
}
},
"hint": {
"text": "Select all options that are relevant to you."
},
"errorMessage": {
"text": "Select how you like to be contacted"
},
"items": [
{
"value": "email",
"text": "Email",
id: "contact"
},
{
"value": "phone",
"text": "Phone"
},
{
"value": "text message",
"text": "Text message"
}
]
}) }}
Where to put the error summary
Put the error summary at the top of the main
container. If your page includes breadcrumbs or a back link, place it below these, but above the <h1>
.
<div class="hs2-width-container">
<div class="hs2-back-link hs2-u-margin-bottom-0 hs2-u-margin-top-4">
<a class="hs2-back-link__link" href="#">
<svg class="hs2-icon hs2-icon__chevron-left" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" height="24" width="24">
<path d="M6.69995 6.82499L8.59995 8.69999L6.62495 10.675L21.325 10.675L21.325 13.325L6.62495 13.325L8.59995 15.3L6.69995 17.175L1.54995 12L6.69995 6.82499Z" />
</svg>
Go back</a>
</div>
<main class="hs2-main-wrapper" id="maincontent" role="main">
<div class="hs2-grid-row">
<div class="hs2-grid-column-two-thirds">
<form>
<div class="hs2-error-summary" aria-labelledby="error-summary-title" role="alert" tabindex="-1">
<h2 class="hs2-error-summary__title" id="error-summary-title">
There is a problem
</h2>
<div class="hs2-error-summary__body">
<ul class="hs2-list hs2-error-summary__list">
<li>
<a href="#dob-errors-year">Date of birth must include a year</a>
</li>
</ul>
</div>
</div>
<div class="hs2-form-group hs2-form-group--error">
<fieldset class="hs2-fieldset" aria-describedby="dob-errors-hint dob-errors-error" role="group">
<legend class="hs2-fieldset__legend hs2-fieldset__legend--l">
<h1 class="hs2-fieldset__heading">
What is your date of birth?
</h1>
</legend>
<div class="hs2-hint" id="dob-errors-hint">
For example, 15 3 1984
</div>
<span class="hs2-error-message" id="dob-errors-error">
<span class="hs2-u-visually-hidden">Error:</span> Date of birth must include a year
</span>
<div class="hs2-date-input" id="dob-errors">
<div class="hs2-date-input__item">
<div class="hs2-form-group">
<label class="hs2-label hs2-date-input__label" for="dob-errors-day">
Day
</label>
<input class="hs2-input hs2-date-input__input hs2-input--width-2" id="dob-errors-day" name="day" type="text" value="15" pattern="[0-9]*" inputmode="numeric">
</div>
</div>
<div class="hs2-date-input__item">
<div class="hs2-form-group">
<label class="hs2-label hs2-date-input__label" for="dob-errors-month">
Month
</label>
<input class="hs2-input hs2-date-input__input hs2-input--width-2" id="dob-errors-month" name="month" type="text" value="3" pattern="[0-9]*" inputmode="numeric">
</div>
</div>
<div class="hs2-date-input__item">
<div class="hs2-form-group">
<label class="hs2-label hs2-date-input__label" for="dob-errors-year">
Year
</label>
<input class="hs2-input hs2-date-input__input hs2-input--width-4 hs2-input--error" id="dob-errors-year" name="year" type="text" pattern="[0-9]*" inputmode="numeric">
</div>
</div>
</div>
</fieldset>
</div>
<button class="hs2-button" type="submit">
Continue
</button>
</form>
</div>
</div>
</main>
</div>
Nunjucks macro options
Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
Some options are required for the macro to work; these are marked as "Required" in the option description.
If you're using Nunjucks macros in production with "html" options, or ones ending with "html", you must sanitise the HTML to protect against cross-site scripting exploits.
Name | Type | Required | Description |
---|---|---|---|
Name titleText | Type string | Required true | Description If `titleHtml` is set, this is not required. Text to use for the heading of the error summary block. If `titleHtml` is provided, `titleText` will be ignored. |
Name titleHtml | Type string | Required true | Description If `titleText` is set, this is not required. HTML to use for the heading of the error summary block. If `titleHtml` is provided, `titleText` will be ignored. |
Name descriptionText | Type string | Required false | Description Text to use for the description of the errors. If you set `descriptionHtml`, the component will ignore `descriptionText`. |
Name descriptionHtml | Type string | Required false | Description HTML to use for the description of the errors. If you set this option, the component will ignore `descriptionText`. |
Name errorList | Type array | Required true | Description Contains an array of error link items and all their available arguments. |
Name errorList[].href | Type string | Required false | Description Href attribute for the error link item. If provided item will be an anchor. |
Name errorList[].text | Type string | Required true | Description If `html` is set, this is not required. Text for the error link item. If `html` is provided, the `text` argument will be ignored. |
Name errorList[].html | Type string | Required true | Description If `text` is set, this is not required. HTML for the error link item. If `html` is provided, the `text` argument will be ignored. |
Name errorList[].attributes | Type object | Required false | Description HTML attributes (for example data attributes) to add to the error link anchor. |
Name classes | Type string | Required false | Description Classes to add to the error-summary container. |
Name attributes | Type object | Required false | Description HTML attributes (for example data attributes) to add to the error-summary container. |
{% from 'back-link/macro.njk' import backLink %}
{% from 'button/macro.njk' import button %}
{% from 'date-input/macro.njk' import dateInput %}
{% from 'error-summary/macro.njk' import errorSummary %}
{% block beforeContent %}
{{ backLink({
"href": "#",
"text": "Go back",
"classes": "hs2-u-margin-bottom-0 hs2-u-margin-top-4"
}) }}
{% endblock %}
{% block content %}
<div class="hs2-grid-row">
<div class="hs2-grid-column-two-thirds">
<form>
{{ errorSummary({
"titleText": "There is a problem",
"errorList": [
{
"text": "Date of birth must include a year",
"href": "#dob-errors-year"
}
]
}) }}
{{ dateInput({
"id": "dob-errors",
"fieldset": {
"legend": {
"text": "What is your date of birth?",
"classes": "hs2-fieldset__legend--l",
"isPageHeading": true
}
},
"hint": {
"text": "For example, 15 3 1984"
},
"errorMessage": {
"text": "Date of birth must include a year"
},
"items": [
{
"name": "day",
"classes": "hs2-input--width-2",
value: 15
},
{
"name": "month",
"classes": "hs2-input--width-2",
value: 3
},
{
"name": "year",
"classes": "hs2-input--width-4 hs2-input--error"
}
]
}) }}
{{ button({
"text": "Continue"
}) }}
</form>
</div>
</div>
{% endblock %}
Research
GOV.UK research on error summaries showed users:
- understood what went wrong
- knew how to fix the problem
- were able to recover from the error