Skip to content

Commit 651185b

Browse files
committed
Document view model props
1 parent 4a6aab4 commit 651185b

4 files changed

Lines changed: 198 additions & 0 deletions

File tree

docs/features/index.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ A library of built-in form components — text fields, date inputs, radio button
1010

1111
Built-in page controllers that define how a page behaves — question pages, repeating groups, file upload pages, summary and confirmation pages.
1212

13+
## [Page Elements](./features/page-elements)
14+
15+
View model properties that the plugin provides for page-level GOV.UK Frontend components — back link, phase banner, page title, service navigation, and footer — which your base layout template must render.
16+
1317
## Advanced
1418

1519
### [Configuration-based Features](./features/configuration-based)

docs/features/page-elements.mdx

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
---
2+
sidebar_label: "Page Elements"
3+
sidebar_position: 2
4+
---
5+
6+
# Page Elements
7+
8+
For each page it renders, the plugin computes a set of view model properties and makes them available to your base layout template — set via `baseLayoutPath` in the [plugin options](../plugin-options.md#nunjucks-configuration). Some of these map directly to GOV.UK Frontend components (back link, phase banner, error summary, service navigation). Others are general metadata about the current page or form (title, name, slug) that your layout can use however it needs to.
9+
10+
None of these are required. The form journey will function without any of them, but omitting them may result in a degraded experience: missing back links, no phase banner, inaccessible page titles, and so on. Use whichever ones apply to your service.
11+
12+
The template block names in the examples below follow the [GOV.UK Frontend page template](https://design-system.service.gov.uk/styles/page-template/).
13+
14+
| Property | Source | Type | Description |
15+
|----------|--------|------|-------------|
16+
| `backLink` | Page view model | `{ text: string; href: string } \| undefined` | Back link macro params, or `undefined` if there is no back navigation |
17+
| `pageTitle` | Page view model | `string` | Title of the current page |
18+
| `name` | Page view model | `string \| undefined` | Form name from the form definition |
19+
| `phaseTag` | Page view model | `string \| undefined` | Phase label from the form definition's `phaseBanner.phase` setting |
20+
| `feedbackLink` | Page view model | `string \| undefined` | URL of the built-in feedback form, or `undefined` if feedback is disabled |
21+
| `serviceUrl` | Page view model | `string` | Root URL of the current form |
22+
| `errors` | Page view model | `FormSubmissionError[] \| undefined` | Validation errors for the current page |
23+
24+
---
25+
26+
## Back link
27+
28+
**Property:** `backLink: { text: string; href: string } | undefined`
29+
30+
The plugin automatically calculates the back link for each page based on the user's journey. The value is ready to pass directly to the GOV.UK Frontend [Back link](https://design-system.service.gov.uk/components/back-link/) macro.
31+
32+
Add the following to your base layout's `beforeContent` block:
33+
34+
```njk
35+
{% from "govuk/components/back-link/macro.njk" import govukBackLink %}
36+
37+
{% block beforeContent %}
38+
{% if backLink %}
39+
{{ govukBackLink(backLink) }}
40+
{% endif %}
41+
{% endblock %}
42+
```
43+
44+
`backLink` is `undefined` on pages with no back navigation — for example, the start page and confirmation page.
45+
46+
<div className="component-preview app-no-prose">
47+
<div dangerouslySetInnerHTML={{ __html: `<a href="#" class="govuk-back-link">Back</a>` }} />
48+
</div>
49+
50+
---
51+
52+
## Phase banner
53+
54+
**Properties:** `phaseTag: string | undefined`, `feedbackLink: string | undefined`
55+
56+
The plugin provides both values for rendering a GOV.UK Frontend [Phase banner](https://design-system.service.gov.uk/components/phase-banner/).
57+
58+
- `phaseTag` comes from the form definition's `phaseBanner.phase` property.
59+
- `feedbackLink` is the URL of the built-in form feedback page (`/form/feedback?formId=...`). It is `undefined` when user feedback is disabled via `disableUserFeedback` in the form definition's options.
60+
61+
If either value is not set by the form definition, you can fall back to a value from your own service configuration:
62+
63+
```njk
64+
{% from "govuk/components/phase-banner/macro.njk" import govukPhaseBanner %}
65+
66+
{% set phaseTag = phaseTag or config.phaseTag %}
67+
{% set feedbackLink = feedbackLink or config.feedbackLink %}
68+
69+
{% if phaseTag %}
70+
{{ govukPhaseBanner({
71+
tag: { text: phaseTag | capitalize },
72+
html: '<a class="govuk-link govuk-link--no-visited-state" href="' + feedbackLink + '" target="_blank" rel="noopener noreferrer">Give feedback</a>'
73+
}) }}
74+
{% endif %}
75+
```
76+
77+
<div className="component-preview app-no-prose">
78+
<div dangerouslySetInnerHTML={{ __html: `<div class="govuk-phase-banner">
79+
<p class="govuk-phase-banner__content">
80+
<strong class="govuk-tag govuk-phase-banner__content__tag">
81+
Beta
82+
</strong>
83+
<span class="govuk-phase-banner__text">
84+
This is a new service – <a class="govuk-link govuk-link--no-visited-state" href="#">give feedback</a>.
85+
</span>
86+
</p>
87+
</div>` }} />
88+
</div>
89+
90+
---
91+
92+
## Error summary
93+
94+
**Property:** `errors: FormSubmissionError[] | undefined`
95+
96+
The plugin populates `errors` with validation failures when a page is submitted with invalid input. Pass it to the GOV.UK Frontend [Error summary](https://design-system.service.gov.uk/components/error-summary/) component, which must appear at the top of the main content area, above the page heading.
97+
98+
The plugin's own page views already render the error summary. This property is listed here because your `pageTitle` block should prefix the title with `"Error: "` when errors are present — a GDS accessibility requirement.
99+
100+
```njk
101+
{% block pageTitle %}
102+
{{ "Error: " if errors | length }}{{ pageTitle }} - {{ name }} - GOV.UK
103+
{% endblock %}
104+
```
105+
106+
<div className="component-preview app-no-prose">
107+
<div dangerouslySetInnerHTML={{ __html: `<div class="govuk-error-summary" data-module="govuk-error-summary">
108+
<div role="alert">
109+
<h2 class="govuk-error-summary__title">
110+
There is a problem
111+
</h2>
112+
<div class="govuk-error-summary__body">
113+
<ul class="govuk-list govuk-error-summary__list">
114+
<li>
115+
<a href="#dob">Enter your date of birth</a>
116+
</li>
117+
<li>
118+
<a href="#email">Enter an email address in the correct format, like name@example.com</a>
119+
</li>
120+
</ul>
121+
</div>
122+
</div>
123+
</div>` }} />
124+
</div>
125+
126+
---
127+
128+
## Page title
129+
130+
**Property:** `pageTitle: string`
131+
132+
The title of the current form page. Use it in your layout's `pageTitle` block to populate the browser `<title>` element. `name` is the form name from the form definition:
133+
134+
```njk
135+
{% block pageTitle %}
136+
{{ "Error: " if errors | length }}{{ pageTitle }} - {{ name }} - GOV.UK
137+
{% endblock %}
138+
```
139+
140+
When a page has validation errors, prefix the title with `"Error: "`. Screen readers announce the page title on load, so this is what alerts users to the presence of errors before they reach the error summary or individual fields. This pattern is documented in the [GDS error summary guidance](https://design-system.service.gov.uk/components/error-summary/#how-it-works).
141+
142+
---
143+
144+
## Header and service navigation
145+
146+
**Properties:** `serviceUrl: string`, `name: string | undefined`
147+
148+
- `serviceUrl` is the root URL of the current form (e.g. `/my-form`). Use it as the service link in your header so users can return to the start of the form.
149+
- `name` is the form name from the form definition. Use it as the service name in your header.
150+
151+
The [GOV.UK Service navigation](https://design-system.service.gov.uk/components/service-navigation/) component is recommended for this from GOV.UK Frontend v5:
152+
153+
```njk
154+
{% from "govuk/components/service-navigation/macro.njk" import govukServiceNavigation %}
155+
156+
{{ govukServiceNavigation({
157+
serviceName: name,
158+
serviceUrl: serviceUrl
159+
}) }}
160+
```
161+
162+
<div className="component-preview app-no-prose">
163+
<div dangerouslySetInnerHTML={{ __html: `<section aria-label="Service information"
164+
class="govuk-service-navigation"
165+
data-module="govuk-service-navigation"
166+
>
167+
<div class="govuk-width-container">
168+
<div class="govuk-service-navigation__container">
169+
<span class="govuk-service-navigation__service-name">
170+
<a href="#" class="govuk-service-navigation__link">
171+
My Service
172+
</a>
173+
</span>
174+
</div>
175+
</div>
176+
</section>` }} />
177+
</div>
178+
179+
---
180+
181+
## Other available properties
182+
183+
The following properties are also available in the template context. They are used internally by the plugin's own page views but can be accessed in your base layout where needed:
184+
185+
| Property | Description |
186+
|----------|-------------|
187+
| `slug` | The form's URL slug (e.g. `my-form`). Only set on successful page responses — `undefined` on error pages. Commonly used to build per-form footer links (privacy, cookies, accessibility statement). |
188+
| `currentPath` | The current page URL including query string. Useful for building redirect URLs (e.g. cookie preference form actions). |
189+
| `context.isForceAccess` | `true` when a form is being viewed in preview mode. Use this to suppress external navigation links. |
190+
| `previewMode` | Set when the form is in a preview state, indicating which preview mode is active. |

docusaurus.config.cjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ const config = {
8080
sidebar: [
8181
{ text: 'Components', href: '/features/components' },
8282
{ text: 'Page Types', href: '/features/pages' },
83+
{ text: 'Page Elements', href: '/features/page-elements' },
8384
{
8485
text: 'Advanced',
8586
href: '/features',

scripts/component-metadata.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@
8484
]
8585
},
8686
"componentLinks": {
87+
"UkAddressField": [
88+
"When `usePostcodeLookup` is enabled, the component uses the Ordnance Survey API to find addresses by postcode. This requires the `ordnanceSurveyApiKey` and `ordnanceSurveyApiSecret` [plugin options](../../plugin-options.md#geospatial-map) to be set — without them the component falls back to the manual address entry form regardless of the `usePostcodeLookup` setting."
89+
],
8790
"FileUploadField": [
8891
"This component renders the list of files already in session state, allows the user to remove individual files, and enforces min/max file count constraints. On final form submission it calls `persistFiles()` to move files to permanent storage. It does not handle uploading — that is the responsibility of the page controller. See [`FileUploadPageController`](../pages/file-upload-page.md) for the provided Defra implementation."
8992
],

0 commit comments

Comments
 (0)