Repository: DFE-Digital/get-into-teaching-app
Pull request #4645: Allow inset text component to take optional heading_tag parameter
Author: login: spencerldixon
Labels: name: ruby
description: Pull requests that update Ruby code
name: test
name: Review
name: Style
name: content
description: Content changes
Created: 2025-03-07T11:20:10Z | Merged: 2025-03-11T11:13:11Z

### Trello card

https://trello.com/c/MDXOSArb/7575-gds-accessibility-audit-7-incorrect-heading-structure-or-visual-appearance-of-non-uk-citizens-component-on-help-and-support-page?filter=member:spencerldixon

### Context

On the Help and support getting into teaching page, the “Talk to us” section has a grey background and visually it appears that everything within this section relates to the level 2 heading of “Talk to us”. However, programmatically, “Non-UK citizens:” within the grey background is also a level 2 heading. The visual information does not match the programmatic structure of the headings.

### Changes proposed in this pull request

- Allow inset text component to take an optional `heading_tag` parameter
- Adjust pages to have appropriate headings depending on structure

### Guidance to review




Diff:
diff --git a/app/components/content/inset_text_component.html.erb b/app/components/content/inset_text_component.html.erb
index fa3b4c6ac2..bb06278d9e 100644
--- a/app/components/content/inset_text_component.html.erb
+++ b/app/components/content/inset_text_component.html.erb
@@ -1,6 +1,6 @@
 <%= tag.section(class: classes) do %>
   <% if header.present? || title.present? %>
-    <%= tag.h2 role: "text" do %>
+    <%= content_tag(heading_tag, role: "text") do %>
       <%= tag.span(header, class: "header") if header.present? %>
       <%= tag.span(title, class: "title") if title.present? %>
     <% end %>
diff --git a/app/components/content/inset_text_component.rb b/app/components/content/inset_text_component.rb
index f4814cd684..6faa0f503b 100644
--- a/app/components/content/inset_text_component.rb
+++ b/app/components/content/inset_text_component.rb
@@ -1,16 +1,17 @@
 module Content
   class InsetTextComponent < ViewComponent::Base
-    attr_reader :header, :title, :text, :color
+    attr_reader :header, :title, :text, :color, :heading_tag
 
     include ContentHelper
 
-    def initialize(text:, title: nil, header: nil, color: "yellow")
+    def initialize(text:, title: nil, header: nil, color: "yellow", heading_tag: "h2")
       super
 
       @text = substitute_values(text)
       @title = substitute_values(title)
       @header = substitute_values(header.present? && title.present? ? "#{header}:" : header)
       @color = color
+      @heading_tag = heading_tag
     end
 
     def classes
diff --git a/app/components/content/talk_to_us_component.html.erb b/app/components/content/talk_to_us_component.html.erb
index 8ae2073ef0..e332bd4ed6 100644
--- a/app/components/content/talk_to_us_component.html.erb
+++ b/app/components/content/talk_to_us_component.html.erb
@@ -28,7 +28,8 @@
           <%= render Content::InsetTextComponent.new(
             header: "Non-UK citizens:",
             text: "You can call us on <a href=\"tel:+448003892500\">+44 800 389 2500</a>, or use the free live chat service. Calls will be charged at your country's standard rate.",
-            color: "purple-white"
+            color: "purple-white",
+            heading_tag: "h3"
           ) %>
       </div>
     </div>
diff --git a/app/components/funding_widget_component.html.erb b/app/components/funding_widget_component.html.erb
index edd396d10f..0f9312f9a3 100644
--- a/app/components/funding_widget_component.html.erb
+++ b/app/components/funding_widget_component.html.erb
@@ -33,7 +33,8 @@
               <%= render Content::InsetTextComponent.new(
                 header: "Non-UK citizens:",
                 text: "You're unlikely to get help funding your training unless you have permission to <a href=\"https://www.gov.uk/browse/visas-immigration/settle-in-the-uk\">live permanently in the UK</a>. Find out about <a href=\"/non-uk-teachers/fees-and-funding-for-non-uk-trainees\">funding for non-UK citizens</a>.",
-                color: "purple-white"
+                color: "purple-white",
+                heading_tag: "h4"
               ) %>
             </div>
           </div>
@@ -51,7 +52,8 @@
                       <p>Other funding like tuition fee loans and maintenance loans are normally only available for UK citizens or non-UK citizens with permission to <a href=\"https://www.gov.uk/browse/visas-immigration/settle-in-the-uk\">live permanently in the UK</a>.</p>
                       <br>
                       <p>Find out about <a href=\"/non-uk-teachers/fees-and-funding-for-non-uk-trainees\">funding for non-UK citizens</a>.</p>",
-                color: "purple-white"
+                color: "purple-white",
+                heading_tag: "h4"
               ) %>
             </div>
           </div>
diff --git a/app/views/content/life-as-a-teacher/change-careers/how-to-change-careers-to-become-a-teacher/_article.html.erb b/app/views/content/life-as-a-teacher/change-careers/how-to-change-careers-to-become-a-teacher/_article.html.erb
index 940f5aa6c2..884cf152a7 100644
--- a/app/views/content/life-as-a-teacher/change-careers/how-to-change-careers-to-become-a-teacher/_article.html.erb
+++ b/app/views/content/life-as-a-teacher/change-careers/how-to-change-careers-to-become-a-teacher/_article.html.erb
@@ -6,7 +6,8 @@
     <%= render Content::InsetTextComponent.new(
       header: "Non-UK citizens:",
       text: "<p>If you're not from the UK, find out about <a href=\"/non-uk-teachers/train-to-teach-in-england-as-an-international-student\">training to teach in England as a non-UK citizen</a>.</p>",
-      color: "purple"
+      color: "purple",
+      heading_tag: "h3"
     ) %>
     <h3>If you have a degree</h3>
     <p>If you already have a degree, you can do a postgraduate teacher training course to gain QTS.</p>
diff --git a/app/views/content/life-as-a-teacher/change-careers/support-with-changing-careers/_article.html.erb b/app/views/content/life-as-a-teacher/change-careers/support-with-changing-careers/_article.html.erb
index 76d619fc7c..7a3f416818 100644
--- a/app/views/content/life-as-a-teacher/change-careers/support-with-changing-careers/_article.html.erb
+++ b/app/views/content/life-as-a-teacher/change-careers/support-with-changing-careers/_article.html.erb
@@ -4,7 +4,8 @@
     <%= render Content::InsetTextComponent.new(
       header: "Non-UK citizens:",
       text: "<p>If you're not from the UK, find out about <a href=\"/non-uk-teachers/train-to-teach-in-england-as-an-international-student\">training to teach in England as a non-UK citizen</a>.</p>",
-      color: "purple"
+      color: "purple",
+      heading_tag: "h2"
     ) %>
     <h2 class="heading--box-blue">Get advice and guidance from an expert</h2>
     <h3>Teacher training advisers</h3>
diff --git a/app/views/teacher_training_adviser/steps/_identity.html.erb b/app/views/teacher_training_adviser/steps/_identity.html.erb
index 542f3a8b12..8195dab114 100644
--- a/app/views/teacher_training_adviser/steps/_identity.html.erb
+++ b/app/views/teacher_training_adviser/steps/_identity.html.erb
@@ -24,7 +24,8 @@
 <%= render Content::InsetTextComponent.new(
   header: "Non-UK citizens:",
   text: "If you qualified as a teacher outside the UK, you need English qualified teacher status (QTS) to get an adviser. <a href=\"/non-uk-teachers/teach-in-england-if-you-trained-overseas\">Find out about teaching in England if you qualified outside the UK</a>.",
-  color: "purple"
+  color: "purple",
+  heading_tag: "h2"
 ) %>
 
 <%= f.govuk_text_field :first_name, width: 'two-thirds', autocomplete: "given-name" %>
diff --git a/app/views/teaching_events/show/_event-summary.html.erb b/app/views/teaching_events/show/_event-summary.html.erb
index c3d6510b43..2e803d440b 100644
--- a/app/views/teaching_events/show/_event-summary.html.erb
+++ b/app/views/teaching_events/show/_event-summary.html.erb
@@ -1,7 +1,7 @@
 <h2>Event information</h2>
 
 <% if @event.message %>
-  <%= render Content::InsetTextComponent.new(text: @event.message) %>
+  <%= render Content::InsetTextComponent.new(text: @event.message, heading_tag: "h3") %>
 <% end %>
 
 <%= tag.div(formatted_event_description(@event.description)) %>
diff --git a/app/views/teaching_events/show/_other-events.erb b/app/views/teaching_events/show/_other-events.html.erb
similarity index 63%
rename from app/views/teaching_events/show/_other-events.erb
rename to app/views/teaching_events/show/_other-events.html.erb
index 0e1bf65dda..8f71794e34 100644
--- a/app/views/teaching_events/show/_other-events.erb
+++ b/app/views/teaching_events/show/_other-events.html.erb
@@ -1,8 +1,9 @@
 <%= render Content::InsetTextComponent.new(
-  title: "Find more events",
+  header: "Find more events",
   color: "grey",
+  heading_tag: "h2",
   text: <<~HTML
     <p>There are lots more online and in-person events where you can get your questions answered about teaching.</p>
-    <p>#{link_to("Explore all events", events_path)}.</p>
-    HTML
+    <p>#{link_to('Explore all events', events_path)}.</p>
+  HTML
 ) %>
diff --git a/app/webpacker/styles/components/inset-text.scss b/app/webpacker/styles/components/inset-text.scss
index 441becfb7e..d2d66709c5 100644
--- a/app/webpacker/styles/components/inset-text.scss
+++ b/app/webpacker/styles/components/inset-text.scss
@@ -19,7 +19,7 @@ section.inset-text {
     border-left-color: $grey-mid;
   }
 
-  h2 {
+  h1, h2, h3, h4, h5, h6 {
     margin-top: 0;
 
     span.header {
@@ -39,8 +39,7 @@ section.inset-text {
     margin-bottom: 0;
   }
 
-  h2,
-  p {
+  h1, h2, h3, h4, h5, h6, p {
     @include font-size("small");
     margin: 0;
   }
diff --git a/docs/content.md b/docs/content.md
index d9305ea35b..8cc5da95a7 100644
--- a/docs/content.md
+++ b/docs/content.md
@@ -295,6 +295,7 @@ If you need to call out something important in a page and differentiate it from
 #### Inset component for non-UK content
 
 You do not need to include both a heading and title in the inset text.
+The heading tag will default to a h2, but you can override this by optionally specifying the `heading_tag` parameter.
 
 ```yaml
 ---
@@ -304,6 +305,7 @@ inset_text:
     title: Optional title
     text: Text that can contain <a href="#">links</a>
     color: yellow|grey|purple|purple-white
+    heading_tag: "h3"
 ---
 
 # My page content
@@ -316,7 +318,8 @@ If you need to insert an inset text component in an erb file:
 <%= render Content::InsetTextComponent.new(
   header: "Non-UK citizens:",
   text: "You can call us on <a href=\"tel:+448003892500\">+44 800 389 2500</a>, or use the free live chat service. Calls will be charged at your country's standard rate.",
-  color: "purple-white"
+  color: "purple-white",
+  heading_tag: "h3"
   ) %>
 ```
 
diff --git a/spec/components/content/inset_text_component_spec.rb b/spec/components/content/inset_text_component_spec.rb
index d0d657610d..491b2a49d1 100644
--- a/spec/components/content/inset_text_component_spec.rb
+++ b/spec/components/content/inset_text_component_spec.rb
@@ -61,4 +61,13 @@
 
     it { is_expected.to have_css("section.inset-text.purple") }
   end
+
+  context "when the heading_tag is overridden" do
+    let(:custom_heading_tag) { "h4" }
+    let(:component) { described_class.new(text: text, header: header, title: title, color: color, heading_tag: custom_heading_tag) }
+
+    specify "the custom heading tag is used" do
+      expect(subject).to have_css(".inset-text #{custom_heading_tag}[role=\"text\"]", text: title)
+    end
+  end
 end


Reviews:
user: login: gemmadallmandfe
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T09:02:19Z
user: login: gemmadallmandfe
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T09:06:33Z
user: login: gemmadallmandfe
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T09:08:27Z
user: login: Sarah-DfE
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T11:14:05Z
user: login: spencerldixon
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T14:17:38Z
user: login: gemmadallmandfe
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T14:21:57Z
user: login: gemmadallmandfe
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T14:22:38Z
user: login: gemmadallmandfe
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T17:58:13Z
user: login: jenhadfield-dfe
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T18:00:45Z
user: login: gemmadallmandfe
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-11T09:40:50Z
user: login: jenhadfield-dfe
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-11T09:50:48Z
user: login: jenhadfield-dfe
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-03-11T09:51:00Z
user: login: gemmadallmandfe
body: Looks good to me from a front end perspective
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-03-11T10:55:44Z
user: login: martyn-w
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-11T10:59:43Z
user: login: martyn-w
body: 👍 LGTM
state: DISMISSED
author_association: COLLABORATOR
submitted_at: 2025-03-11T11:00:26Z
user: login: martyn-w
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-11T11:03:32Z
user: login: gemmadallmandfe
body: Looks good to me
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-11T11:12:18Z

Review comments:
diff_hunk: @@ -1,6 +1,7 @@
 <%= render Content::InsetTextComponent.new(
   title: "Find more events",
   color: "grey",
+  heading_tag: "h2",
path: app/views/teaching_events/show/_other-events.html.erb
user: login: gemmadallmandfe
body: This looks fine in terms of heading structure but the styling is odd - it doesn't look like a heading at all

Since we are changing the heading_tag @spencerldixon, would it be possible to change the styling here as well so that it visibly looks like a heading?

(Separate ticket on this which I'll bring onto the board: https://trello.com/c/IKzXiAQ9)
created_at: 2025-03-10T09:02:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -6,7 +6,8 @@
     <%= render Content::InsetTextComponent.new(
       header: "Non-UK citizens:",
       text: "<p>If you're not from the UK, find out about <a href=\"/non-uk-teachers/train-to-teach-in-england-as-an-international-student\">training to teach in England as a non-UK citizen</a>.</p>",
-      color: "purple"
+      color: "purple",
+      heading_tag: "h3"
path: app/views/content/life-as-a-teacher/change-careers/how-to-change-careers-to-become-a-teacher/_article.html.erb
user: login: gemmadallmandfe
body: The heading tag looks right but the styling has now changed @spencerldixon ! Maybe one to discuss with @jenhadfield-dfe ?

![image](https://github.com/user-attachments/assets/2ab0b83c-d5ca-4773-92f1-be8190ea6ff5)

created_at: 2025-03-10T09:06:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -24,7 +24,8 @@
 <%= render Content::InsetTextComponent.new(
   header: "Non-UK citizens:",
   text: "If you qualified as a teacher outside the UK, you need English qualified teacher status (QTS) to get an adviser. <a href=\"/non-uk-teachers/teach-in-england-if-you-trained-overseas\">Find out about teaching in England if you qualified outside the UK</a>.",
-  color: "purple"
+  color: "purple",
+  heading_tag: "h2"
path: app/views/teacher_training_adviser/steps/_identity.html.erb
user: login: gemmadallmandfe
body: @Sarah-DfE @emmaachesongray Could you have a look at this please and see whether we need to add a separate h2 above the form? Otherwise the form will sit in the Non-UK h2 section which doesn't feel right
created_at: 2025-03-10T09:08:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -24,7 +24,8 @@
 <%= render Content::InsetTextComponent.new(
   header: "Non-UK citizens:",
   text: "If you qualified as a teacher outside the UK, you need English qualified teacher status (QTS) to get an adviser. <a href=\"/non-uk-teachers/teach-in-england-if-you-trained-overseas\">Find out about teaching in England if you qualified outside the UK</a>.",
-  color: "purple"
+  color: "purple",
+  heading_tag: "h2"
path: app/views/teacher_training_adviser/steps/_identity.html.erb
user: login: Sarah-DfE
body: @gemmadallmandfe agree, a h2 above the form makes sense
created_at: 2025-03-10T11:14:05Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,6 +1,7 @@
 <%= render Content::InsetTextComponent.new(
   title: "Find more events",
   color: "grey",
+  heading_tag: "h2",
path: app/views/teaching_events/show/_other-events.html.erb
user: login: spencerldixon
body: I've fixed this but I think there's another issue here, we have `title` and `header`. Headers will render the bold style, but titles will not be bold. Both are fixed to a font size of `small`. Is there the need for both here? Could we get rid of `title` and should headings be allowed to be bigger depending on h1, h2 etc, or should they always be fixed to a `small` font size?
created_at: 2025-03-10T14:17:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -24,7 +24,8 @@
 <%= render Content::InsetTextComponent.new(
   header: "Non-UK citizens:",
   text: "If you qualified as a teacher outside the UK, you need English qualified teacher status (QTS) to get an adviser. <a href=\"/non-uk-teachers/teach-in-england-if-you-trained-overseas\">Find out about teaching in England if you qualified outside the UK</a>.",
-  color: "purple"
+  color: "purple",
+  heading_tag: "h2"
path: app/views/teacher_training_adviser/steps/_identity.html.erb
user: login: gemmadallmandfe
body: Separate ticket raised for this to be done on a separate PR, so resolving this conversation here
created_at: 2025-03-10T14:21:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,6 +1,7 @@
 <%= render Content::InsetTextComponent.new(
   title: "Find more events",
   color: "grey",
+  heading_tag: "h2",
path: app/views/teaching_events/show/_other-events.html.erb
user: login: gemmadallmandfe
body: Calling @jenhadfield-dfe for advice!
created_at: 2025-03-10T14:22:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,6 +1,7 @@
 <%= render Content::InsetTextComponent.new(
   title: "Find more events",
   color: "grey",
+  heading_tag: "h2",
path: app/views/teaching_events/show/_other-events.html.erb
user: login: gemmadallmandfe
body: This looks fine to me now @spencerldixon 

Are you happy with this @jenhadfield-dfe ?
created_at: 2025-03-10T17:58:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,6 +1,7 @@
 <%= render Content::InsetTextComponent.new(
   title: "Find more events",
   color: "grey",
+  heading_tag: "h2",
path: app/views/teaching_events/show/_other-events.html.erb
user: login: jenhadfield-dfe
body: yes looks good. but im not sure about the fixed to small font size - i think yes in most cases
created_at: 2025-03-10T18:00:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,6 +1,7 @@
 <%= render Content::InsetTextComponent.new(
   title: "Find more events",
   color: "grey",
+  heading_tag: "h2",
path: app/views/teaching_events/show/_other-events.html.erb
user: login: gemmadallmandfe
body: @jenhadfield-dfe Just to be clear - Spencer is going to get rid of `title` and get this merged, unless you object!

Happy with that?
created_at: 2025-03-11T09:40:50Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,6 +1,7 @@
 <%= render Content::InsetTextComponent.new(
   title: "Find more events",
   color: "grey",
+  heading_tag: "h2",
path: app/views/teaching_events/show/_other-events.html.erb
user: login: jenhadfield-dfe
body: yea that works for me!
created_at: 2025-03-11T09:50:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,6 +1,6 @@
 <%= tag.section(class: classes) do %>
   <% if header.present? || title.present? %>
-    <%= tag.h2 role: "text" do %>
+    <%= content_tag(@heading_tag, role: "text") do %>
path: app/components/content/inset_text_component.html.erb
user: login: martyn-w
body: I think the `@` is unnecessary here? i.e.
```
<%= content_tag(heading_tag, role: "text") do %>
```
created_at: 2025-03-11T10:59:43Z
author_association: COLLABORATOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-03-11T11:09:39Z
body: Review app deployed to https://get-into-teaching-app-review-4645.test.teacherservices.cloud
<!-- Sticky Pull Request CommentAKS -->
author_association: NONE
user: login: sonarqubecloud[bot]
created_at: 2025-03-11T11:10:39Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=DFE-Digital_get-into-teaching-app&pullRequest=4645) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [12 New issues](https://sonarcloud.io/project/issues?id=DFE-Digital_get-into-teaching-app&pullRequest=4645&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [8 Accepted issues](https://sonarcloud.io/project/issues?id=DFE-Digital_get-into-teaching-app&pullRequest=4645&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=DFE-Digital_get-into-teaching-app&pullRequest=4645&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [95.5% Coverage on New Code](https://sonarcloud.io/component_measures?id=DFE-Digital_get-into-teaching-app&pullRequest=4645&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.3% Duplication on New Code](https://sonarcloud.io/component_measures?id=DFE-Digital_get-into-teaching-app&pullRequest=4645&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=DFE-Digital_get-into-teaching-app&pullRequest=4645)


author_association: NONE