v10.5.0
10.5.0 - 2 June 2026
Note: This release was created from the support/10.x branch.
🆕 New features
New search input component
We've added a new search input component.
To use the searchInput Nunjucks macro in your service:
{{ searchInput({
label: {
text: "Find session"
},
name: "search",
width: 10
}) }}If you are not using Nunjucks macros, use the HTML markup from the search input examples in the NHS digital service manual.
This change was introduced in pull request #1660: Add search input component.
Improved character count counting
We've added a new countType option to the character count component to enable improved counting with Intl.Segmenter.
This feature was introduced because JavaScript counts String: length in code units not characters, for example:
| String | Length | Remarks |
|---|---|---|
| cafȩ́ | 5 | The character ȩ́ counted as 2 code units |
| cafȩ́ | 5 | The character ȩ with combining mark ́ counted as 2 code units |
| cafȩ́ | 6 | The character e with combining marks ́ and ̧ counted as 3 code units |
| 😹 | 2 | The cat emoji counted as 2 code units |
| 👩🏻🚀 | 7 | The astronaut emoji with gender and skin modifiers counted as 7 code units |
Similarly when counting words, "my mother-in-law" is now counted as 4 (not 2) words to correctly follow the Unicode Default Word Boundary Specification.
To enable improved counting in supported browsers you should either:
- add
countType: "characters"to count user-perceived characters - add
countType: "words"to count words between word boundaries
Unsupported browsers will default to the textareaDescriptionText message shown when JavaScript is unavailable, such as:
You can enter up to 350 characters
When using Nunjucks to count characters:
{{ characterCount({
label: {
text: "Can you provide more detail?",
size: "l",
isPageHeading: true
},
name: "more-detail",
- maxlength: 350
+ maxlength: 350,
+ countType: "characters"
}) }}Or when using Nunjucks to count words:
{{ characterCount({
label: {
text: "Can you provide more detail?",
size: "l",
isPageHeading: true
},
name: "more-detail",
- maxwords: 150
+ maxlength: 150,
+ countType: "words"
}) }}Note: The character count maxwords option and word counting behaviour are deprecated and will be removed in a future release. You must replace maxwords with maxlength when using countType: "words".
This was added in pull requests #1892: Refactor character count method to reduce repeated updates, #1893: Deprecate character count maxwords and add countType option, #1895: Add character count countType: "characters" option using Intl.Segmenter and #1899: Add character count countType: "words" option using Intl.Segmenter.
Custom character count functions
We've added a new countFunction option to the character count component.
Service teams can now cater for server-side differences in:
- New lines that vary due to
\nversus\r\n - Word counts that vary based on empty space and punctuation
- How empty space is trimmed before counting
- Support for multi-byte strings
For example, services might already count multi-byte strings server-side (e.g. len() in Python) resulting in client-side count mismatches, yet support for improved character count counting may be blocked by a 3rd party library integration.
Custom count functions are called with:
text(string) - Textarea valuecontext(object) - Character count context
new CharacterCount($root, {
maxlength: 350,
countType: 'characters',
countFunction(text, context) {
return text.length
}
})Character count context objects contain the following properties:
$textarea- Textarea HTML elementconfig- Character count configsegmenter- Character countIntl.Segmenter(optional)
Our built in count functions are available to call or extend via:
CharacterCount.countFunctions.length
CharacterCount.countFunctions.characters
CharacterCount.countFunctions.wordsThis was added in pull request #1897: Add character count countFunction option.
Add date input day, month and year Nunjucks options
We've updated the date input component to add individual day, month and year Nunjucks options.
These new options can be used to partially override the defaults. For example, setting error: true on the year item no longer requires all other item defaults to be set:
{{ dateInput({
fieldset: {
legend: {
text: "What is your date of birth?",
size: "l",
isPageHeading: true
}
},
errorMessage: {
text: "Date of birth must include a year"
},
namePrefix: "dob",
values: data.dob,
- items: [
- {
- name: "day",
- label: "Day",
- width: 2
- },
- {
- name: "month",
- label: "Month",
- width: 2
- },
- {
- name: "year",
- label: "Year",
- width: 4,
- error: true
- }
- ]
+ year: {
+ error: true
+ }
}) }}This was added in pull request #1869: Add date input day, month and year options.
Updated Nunjucks macro options for components
For consistency with other components, we’ve added new Nunjucks macro options:
- Action link
elementandtypeoptions - Back link
typeoption - Character count
autocompleteoption - Checkboxes and radios
formGroup.classesoption - Date input and password input
inputWrapperoption - Password input
code,prefixandsuffixoptions - Password input button
variantoption - Radios
formGroup.classesoption
Visit the design system in the NHS digital service manual to see Nunjucks options for each component.
This was added in pull requests #1916: Add disabled component examples and review Nunjucks options and #1946: Updates to link classes and mixins, support for action link as a button.
Added a top-level disabled Nunjucks option to more form controls
We’ve updated more components to include a top-level disabled Nunjucks option. This will make it easier to set the disabled state for these form controls.
- Character count
disabledoption - Checkboxes and radios
disabledoption - Date input
disabledoption - Password input
disabledoption
Disabled form controls have poor contrast and can confuse some users, so avoid them if possible.
Only use disabled form controls if research shows it makes the user interface easier to understand.
This was added in pull request #1916: Add disabled component examples and review Nunjucks options.
Add icons to buttons
You can now add icons to buttons using the icon Nunjucks options.
For example, using icon: "search" to add an icon-only search button to a text input:
{{ input({
formGroup: {
afterInput: {
html: button({
ariaLabel: "Find",
icon: "search",
small: true
})
}
}
}) }}With support for both an icon and text shown together:
html: button({
- ariaLabel: "Find",
+ text: "Find",
icon: "search",
small: true
})Or to change the icon and adjust placement:
html: button({
text: "Find",
- icon: "search",
+ icon: {
+ name: "arrow-right",
+ placement: "end"
+ }
})This was added in pull request #1712: Add support for icon buttons.
Add icons using SVGs
You can also add icons using SVG files in the nhsuk-frontend/dist/nhsuk/assets directory:
images/nhsuk-icon-arrow-down-circle.svgimages/nhsuk-icon-arrow-down.svgimages/nhsuk-icon-arrow-left-circle.svgimages/nhsuk-icon-arrow-left.svgimages/nhsuk-icon-arrow-right-circle.svgimages/nhsuk-icon-arrow-right.svgimages/nhsuk-icon-arrow-up-circle.svgimages/nhsuk-icon-arrow-up.svgimages/nhsuk-icon-chevron-down-circle.svgimages/nhsuk-icon-chevron-left-circle.svgimages/nhsuk-icon-chevron-right-circle.svgimages/nhsuk-icon-chevron-up-circle.svgimages/nhsuk-icon-cross.svgimages/nhsuk-icon-minus.svgimages/nhsuk-icon-plus.svgimages/nhsuk-icon-search.svgimages/nhsuk-icon-tick.svgimages/nhsuk-icon-user.svg
If you use Sass and you've changed the default /assets/ public path (for example, Nunjucks assetPath), make sure $nhsuk-assets-path is configured:
@forward "nhsuk-frontend/dist/nhsuk" with (
+ $nhsuk-assets-path: "/public/assets/",
$nhsuk-fonts-path: "https://assets.nhs.uk/fonts/"
);This was added in pull request #1915: Render Nunjucks icon macro into SVG files.
Add a modifier class for inline checkboxes
We've added a new .nhsuk-checkboxes--inline class and inline Nunjucks option for the checkboxes component.
If there are only 2 short options, you can use this to display the checkboxes horizontally (inline). On small screens such as mobile devices, the checkboxes will still stack vertically.
For example:
{{ checkboxes({
fieldset: {
legend: {
text: "Which nipple has changed?"
}
},
name: "area",
+ inline: true,
items: [
{
value: "right",
text: "Right nipple"
},
{
value: "left",
text: "Left nipple"
}
]
}) }}This was added in pull request #1937: Add a modifier class for inline checkboxes.
Add a template with all components imported
If you are using our Nunjucks page template, you can now extend template-with-imports.njk instead of template.njk to automatically import all components.
This was added in pull request #1921: Add a template with all components imported.
Style links with text colour
You can now style links with text colour by adding the nhsuk-link--text-colour HTML class, or by including the Sass mixin for custom components:
.app-component__link {
@include nhsuk-link-style-text;
}This was added in pull request #1946: Updates to link classes and mixins, support for action link as a button.
Style links to remove underlines
You can now remove underlines from links by adding the nhsuk-link--no-underline HTML class, or by including the Sass mixin for custom components:
.app-component__link {
@include nhsuk-link-style-no-underline;
}An underline still appears when the user hovers their cursor over the link.
This was added in pull request #1946: Updates to link classes and mixins, support for action link as a button.
🗑️ Deprecated features
Rename the character count maxwords option
To support improved word counting using the browser Intl.Segmenter API, you should replace the character count maxwords option with maxlength and set countType: "words".
For example, using Nunjucks:
{{ characterCount({
label: {
text: "Can you provide more detail?",
size: "l",
isPageHeading: true
},
name: "more-detail",
- maxwords: 150
+ maxlength: 150,
+ countType: "words"
}) }}Or when using the JavaScript API:
new CharacterCount($root, {
- maxwords: 150
+ maxlength: 150,
+ countType: 'words'
})The previous maxwords option and word counting behaviour are deprecated and will be removed in a future release.
This change was introduced in pull requests #1893: Deprecate character count maxwords and add countType option and #1899: Add character count countType: "words" option using Intl.Segmenter.
Rename Sass mixin for white link style
If you use the Sass nhsuk-link-style-white mixin, you should rename it to nhsuk-link-style-reverse.
The previous name is deprecated and will be removed in a future release.
This change was introduced in pull request #1946: Updates to link classes and mixins, support for action link as a button.
♻️ Changes
Change border colour for details component and conditionally revealed content
We've changed the border colour shown to the left of details component and conditionally revealed content.
- Details component border colour changed from grey-4 (
#d8dde0) to grey-3 (#aeb7bd) - Conditionally revealed border colour changed from grey-1 (
#4c6272) to grey-3 (#aeb7bd)
This change was introduced in pull request #1788: Change border colour for details component and conditionally revealed content.
Update search and tick icon SVG paths
SVG paths for the search and tick icons have been updated for improved vertical alignment. You do not need to do anything if you're using Nunjucks macros.
If you are not using Nunjucks macros, update your SVG paths using the icon examples in the NHS digital service manual as shown below.
To update the search icon:
<svg class="nhsuk-icon nhsuk-icon--search" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" focusable="false" aria-hidden="true">
- <path d="m20.7 19.3-4.1-4.1a7 7 0 1 0-1.4 1.4l4 4.1a1 1 0 0 0 1.5 0c.4-.4.4-1 0-1.4ZM6 11a5 5 0 1 1 10 0 5 5 0 0 1-10 0Z"/>
+ <path d="m20.7 18.9-4.1-4.1a7 7 0 1 0-1.4 1.4l4 4.1a1 1 0 0 0 1.5 0c.4-.4.4-1 0-1.4ZM6 10.6a5 5 0 1 1 10 0 5 5 0 0 1-10 0Z"/>
</svg>To update the tick icon:
<svg class="nhsuk-icon nhsuk-icon--tick" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" focusable="false" aria-hidden="true">
- <path d="M11.4 18.8a2 2 0 0 1-2.7.1h-.1L4 14.1a1.5 1.5 0 0 1 2.1-2L10 16l8.1-8.1a1.5 1.5 0 1 1 2.2 2l-8.9 9Z"/>
+ <path d="M11.4 17.5a2 2 0 0 1-2.7.1h-.1L4 12.8a1.5 1.5 0 0 1 2.1-2L10 14.7l8.1-8.1a1.5 1.5 0 1 1 2.2 2l-8.9 9Z"/>
</svg>This change was introduced in pull request #1951: Improve vertical alignment for search and tick SVG icon paths.
Improve screen reader announcements for header search button
We've updated the HTML for the header search button to improve NVDA screen reader announcements.
If you are not using Nunjucks macros, update your HTML markup using the header examples in the NHS digital service manual as follows:
- add the
aria-label="Search"attribute to the<button>element - remove the
aria-label="Search"androle="img"attributes from the<svg>icon - remove the
<title>Search</title>child element from the<svg>icon - add the
aria-hidden="true"attribute to the<svg>icon - update the search icon SVG path (if not done already)
- <button class="nhsuk-button nhsuk-button--small" data-module="nhsuk-button" type="submit">
+ <button class="nhsuk-button nhsuk-button--small" data-module="nhsuk-button" type="submit" aria-label="Search">
- <svg class="nhsuk-icon nhsuk-icon--search" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" focusable="false" role="img" aria-label="Search">
+ <svg class="nhsuk-icon nhsuk-icon--search" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" focusable="false">
- <title>Search</title>
- <path d="m20.7 19.3-4.1-4.1a7 7 0 1 0-1.4 1.4l4 4.1a1 1 0 0 0 1.5 0c.4-.4.4-1 0-1.4ZM6 11a5 5 0 1 1 10 0 5 5 0 0 1-10 0Z"/>
+ <path d="m20.7 18.9-4.1-4.1a7 7 0 1 0-1.4 1.4l4 4.1a1 1 0 0 0 1.5 0c.4-.4.4-1 0-1.4ZM6 10.6a5 5 0 1 1 10 0 5 5 0 0 1-10 0Z"/>
</svg>
</button>This change was introduced in pull request #1712: Add support for icon buttons.
🔧 Fixes
- #1890: Refactor character count method to reduce repeated updates
- #1904: Make sure Nunjucks text-only options for card heading, label and legend are escaped
- #1925: Increase text input prefix/suffix spacing
- #1934: Adjust small checkboxes and radios spacing
- #1935: Prevent empty error message being rendered