Overview
This vignette covers all functions in shinyGovstyle that produce styled text content: headings, body text, lists, callout components, links, and typography. For page structure and layout, see the Layout options vignette.
heading_text()
Creates a semantic HTML heading element with a GOV.UK heading CSS class.
heading_text("Summary", size = "l", level = 2)Arguments
| Argument | Default | Description |
|---|---|---|
text_input |
— | The heading text to display |
size |
"xl" |
Visual size: "xl", "l", "m",
or "s"
|
level |
1 |
HTML heading level: integer 1–6 |
id |
auto | Element ID — auto-generated from text_input if
omitted |
Visual size and semantic level are independent
size controls the CSS class applied
(govuk-heading-xl, govuk-heading-l, etc.),
which determines how the heading looks. level controls the
HTML element used (<h1>, <h2>,
etc.), which determines its position in the document outline read by
screen readers and assistive technologies.
These are independent because it is occasionally necessary to use a
smaller visual heading at a higher semantic level, or vice versa. For
example, a page where the first visible heading needs to be modest in
size but is still structurally the <h1>:
heading_text("User guide", size = "m", level = 1)Always set both arguments deliberately. Do not leave
level at its default of 1 for every heading on
a page.
Recommended size–level pairings
Standard pages (most dashboards and data tools):
| Heading role | size |
level |
|---|---|---|
| Page title | "l" |
1 |
| Section heading | "m" |
2 |
| Sub-section heading | "s" |
3 |
Long-form content (user guides, methodology, accessibility statements):
| Heading role | size |
level |
|---|---|---|
| Page title | "xl" |
1 |
| Section heading | "l" |
2 |
| Sub-section heading | "m" |
3 |
| Sub-sub-section heading | "s" |
4 |
Accessibility
Do not skip heading levels. Moving from an
<h1> straight to an <h3> breaks
the document outline and makes it harder for screen reader users to
navigate, as they commonly jump between headings to scan a page. This is
a requirement under WCAG
2.2 success criterion 1.3.1: Info and Relationships.
Write headings in sentence case. Only capitalise the first word and proper nouns.
# Correct — sentence case
heading_text("Summary of findings", size = "l", level = 1)
# Incorrect — title case
heading_text("Summary Of Findings", size = "l", level = 1)For more information, read the GOV.UK headings guidance.
Heading IDs
If id is not supplied it is auto-generated by
lowercasing text_input and replacing non-alphanumeric
characters with underscores. Supply an explicit id when you
need a stable anchor to link to, or when two headings would otherwise
generate the same ID:
heading_text("Methodology", size = "l", level = 2, id = "methodology")
gov_text()
A wrapper that produces a <p class="govuk-body">
paragraph element. Use it when you want to add body text with correct
GOV.UK styling without writing raw tag calls.
gov_list()
Creates a GOV.UK-styled list. The style argument
controls both the HTML element used and the visual presentation:
style |
HTML element | Appearance |
|---|---|---|
"none" (default) |
<ul> |
Plain, no markers |
"bullet" |
<ul> |
Bulleted list |
"number" |
<ol> |
Numbered list |
gov_list(c("First item", "Second item", "Third item"), style = "bullet")
gov_list(c("First step", "Second step", "Third step"), style = "number")Use style = "number" when order matters — steps in a
process, ranked results, or sequential instructions. Use
style = "bullet" for unordered items. The plain style
("none") is useful when you want list semantics for screen
readers without a visual marker.
For more information, read the GOV.UK lists guidance.
insert_text()
Displays a GOV.UK inset text box — a bordered callout for supplementary information that is related to, but not the main focus of, the surrounding content.
insert_text(
inputId = "processing-note",
text = "It can take up to 8 weeks to process your application."
)Use inset text for information the user needs to know but that is not
the primary action or decision on the page — for example, a processing
time, an exception to a rule, or a clarification. Do not use it for
warnings about consequences; use warning_text()
instead.
For more information, read the GOV.UK inset text guidance.
warning_text()
Displays a GOV.UK warning text component: a bold statement with a prominent “!” icon, used to warn users about something with serious consequences.
warning_text(
inputId = "fine-warning",
text = "You can be fined up to £5,000 if you do not register."
)The “!” icon carries aria-hidden = "true" and the word
“Warning” is prepended as visually hidden text, so screen readers
announce “Warning: [your text]” without reading out the icon character.
Given this, you should avoid starting the text with ‘Warning’, else
you’ll submit users to ‘Warning Warning’.
Use warning_text() when the consequence of missing the
information is serious. For less critical supplementary information, use
insert_text() instead.
For more information, read the GOV.UK warning text guidance.
noti_banner()
Displays a GOV.UK notification banner for information that is not directly related to the current page content — such as a service-wide problem, an upcoming deadline, or the outcome of a previous action.
Two types
Standard (default, blue): for neutral information such as service problems or upcoming events.
noti_banner(
inputId = "service-notice",
title_txt = "Important",
body_txt = paste0(
"This service will be unavailable on Saturday ",
"14 June from 8am to 6pm."
)
)Success (green): to confirm that a previous action
completed successfully. Uses role="alert" so screen readers
announce it automatically on page load.
noti_banner(
inputId = "submission-confirm",
title_txt = "Success",
body_txt = "Your report has been submitted.",
type = "success"
)When to use each component
| Situation | Component |
|---|---|
| Information not related to the current page task | noti_banner() |
| Supplementary information related to the page | insert_text() |
| Serious consequences if the user misses information | warning_text() |
| Form validation errors |
error_summary() / error messages |
Use notification banners sparingly — users often overlook them when they appear frequently. Show only one at a time, and never alongside an error summary.
For more information, read the GOV.UK notification banner guidance.
external_link()
A wrapper for HTML anchor elements that produces safe, accessible external links with consistent behaviour.
external_link("https://www.example.gov.uk/guidance", "Guidance for applicants")What the function does automatically
- Adds
target="_blank"to open the link in a new tab - Adds
rel="noopener noreferrer"to prevent reverse tabnabbing - Appends “(opens in new tab)” to the visible link text by default
- Adds a visually hidden “(opens in new tab)” span for screen readers
when
add_warning = FALSE
Descriptive link text
The function validates link_text and will error if you
supply a raw URL as the link text, vague text such as “click here” or
“here”, or text ending with a full stop. It will also warn if the text
is fewer than 7 characters.
This enforces WCAG 2.2 success criterion 2.4.4: Link Purpose (In Context), which requires link text to describe the destination without needing the surrounding context to make sense of it.
# Correct — descriptive
external_link("https://www.example.gov.uk/apply", "Apply for a licence")
# Will error — vague text
external_link("https://www.example.gov.uk/apply", "click here")
# Will error — raw URL as text
external_link(
"https://www.example.gov.uk/apply",
"https://www.example.gov.uk/apply"
)Grouped links
When displaying several external links together, repeating “(opens in
new tab)” on each is visually repetitive. Set
add_warning = FALSE and add a single explanatory sentence
above the group instead:
gov_text("The following links open in a new tab.")
shiny::tags$ul(
shiny::tags$li(
external_link(
"https://www.example.gov.uk/a",
"Guidance document A",
add_warning = FALSE
)
),
shiny::tags$li(
external_link(
"https://www.example.gov.uk/b",
"Guidance document B",
add_warning = FALSE
)
)
)For more information, read the GOV.UK links guidance.
font()
GDS Transport is a restricted typeface and must only be used
on GOV.UK domains. If your app is not hosted on a GOV.UK
domain, do not call font(). You do not need to do anything
and your app will default to Arial instead, which is the correct
behaviour.
If you are on a GOV.UK domain and therefore want to use the
font() function, putting it within your UI will load the
GDS Transport typeface for use in your app. By default the GOV.UK
Frontend CSS specifies
font-family: GDS Transport, arial, sans-serif — if the font
files are not loaded the browser falls back to Arial automatically.
# Only include this if your app is on a GOV.UK domain
font()For more information on when GDS Transport is permitted, read the GOV.UK typeface guidance.
