Skip to content

[SPIKE][WIP] Test different language switchers in govuk-frontend#7141

Draft
domoscargin wants to merge 2 commits into
mainfrom
spike-language-switch-nav
Draft

[SPIKE][WIP] Test different language switchers in govuk-frontend#7141
domoscargin wants to merge 2 commits into
mainfrom
spike-language-switch-nav

Conversation

@domoscargin

@domoscargin domoscargin commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Several options integrated into the service nav without creating a new component.

Welsh/English toggle below the service name
below service name

Welsh/English toggle right-aligned to main nav
right-aligned

Welsh/English toggle with icon
with icon

Multi-language switcher, responsive
list

viewport small viewport small, expanded

Spike-y code not for reuse - more about testing various things.

Next steps:

  • Review examples
  • Start creating a robust component

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown

JavaScript changes to npm package

diff --git a/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js b/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js
index c6b4affdd..34800ce80 100644
--- a/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js
+++ b/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js
@@ -9,20 +9,20 @@ function getBreakpoint(t) {
 }
 
 function setFocus(t, e = {}) {
-    var i;
-    const n = t.getAttribute("tabindex");
+    var n;
+    const i = t.getAttribute("tabindex");
 
     function onBlur() {
-        var i;
-        null == (i = e.onBlur) || i.call(t), n || t.removeAttribute("tabindex")
+        var n;
+        null == (n = e.onBlur) || n.call(t), i || t.removeAttribute("tabindex")
     }
-    n || t.setAttribute("tabindex", "-1"), t.addEventListener("focus", (function() {
+    i || t.setAttribute("tabindex", "-1"), t.addEventListener("focus", (function() {
         t.addEventListener("blur", onBlur, {
             once: !0
         })
     }), {
         once: !0
-    }), null == (i = e.onBeforeFocus) || i.call(t), t.focus()
+    }), null == (n = e.onBeforeFocus) || n.call(t), t.focus()
 }
 
 function isSupported(t = document.body) {
@@ -63,12 +63,12 @@ class ElementError extends GOVUKFrontendError {
         let e = "string" == typeof t ? t : "";
         if (isObject(t)) {
             const {
-                component: i,
-                identifier: n,
+                component: n,
+                identifier: i,
                 element: s,
                 expectedType: o
             } = t;
-            e = n, e += s ? ` is not of type ${null!=o?o:"HTMLElement"}` : " not found", i && (e = formatErrorMessage(i, e))
+            e = i, e += s ? ` is not of type ${null!=o?o:"HTMLElement"}` : " not found", n && (e = formatErrorMessage(n, e))
         }
         super(e), this.name = "ElementError"
     }
@@ -93,8 +93,8 @@ class Component {
             expectedType: e.elementType.name
         });
         this._$root = t, e.checkSupport(), this.checkInitialised();
-        const i = e.moduleName;
-        this.$root.setAttribute(`data-${i}-init`, "")
+        const n = e.moduleName;
+        this.$root.setAttribute(`data-${n}-init`, "")
     }
     checkInitialised() {
         const t = this.constructor,
@@ -116,103 +116,103 @@ class ConfigurableComponent extends Component {
     get config() {
         return this._config
     }
-    constructor(e, i) {
+    constructor(e, n) {
         super(e), this._config = void 0;
-        const n = this.constructor;
-        if (!isObject(n.defaults)) throw new ConfigError(formatErrorMessage(n, "Config passed as parameter into constructor but no defaults defined"));
+        const i = this.constructor;
+        if (!isObject(i.defaults)) throw new ConfigError(formatErrorMessage(i, "Config passed as parameter into constructor but no defaults defined"));
         const s = function(Component, t) {
             if (!isObject(Component.schema)) throw new ConfigError(formatErrorMessage(Component, "Config passed as parameter into constructor but no schema defined"));
             const e = {},
-                i = Object.entries(Component.schema.properties);
-            for (const n of i) {
-                const [i, s] = n, o = i.toString();
-                o in t && (e[o] = normaliseString(t[o], s)), "object" === (null == s ? void 0 : s.type) && (e[o] = extractConfigByNamespace(Component.schema, t, i))
+                n = Object.entries(Component.schema.properties);
+            for (const i of n) {
+                const [n, s] = i, o = n.toString();
+                o in t && (e[o] = normaliseString(t[o], s)), "object" === (null == s ? void 0 : s.type) && (e[o] = extractConfigByNamespace(Component.schema, t, n))
             }
             return e
-        }(n, this._$root.dataset);
-        this._config = mergeConfigs(n.defaults, null != i ? i : {}, this[t](s), s)
+        }(i, this._$root.dataset);
+        this._config = mergeConfigs(i.defaults, null != n ? n : {}, this[t](s), s)
     }
 }
 
 function normaliseString(t, e) {
-    const i = t ? t.trim() : "";
-    let n, s = null == e ? void 0 : e.type;
-    switch (s || (["true", "false"].includes(i) && (s = "boolean"), i.length > 0 && isFinite(Number(i)) && (s = "number")), s) {
+    const n = t ? t.trim() : "";
+    let i, s = null == e ? void 0 : e.type;
+    switch (s || (["true", "false"].includes(n) && (s = "boolean"), n.length > 0 && isFinite(Number(n)) && (s = "number")), s) {
         case "boolean":
-            n = "true" === i;
+            i = "true" === n;
             break;
         case "number":
-            n = Number(i);
+            i = Number(n);
             break;
         default:
-            n = t
+            i = t
     }
-    return n
+    return i
 }
 
 function normaliseOptions(t) {
-    let e, i = document;
+    let e, n = document;
     if (isObject(t)) {
-        const n = t;
-        (isScope(n.scope) || null === n.scope) && (i = n.scope), "function" == typeof n.onError && (e = n.onError)
+        const i = t;
+        (isScope(i.scope) || null === i.scope) && (n = i.scope), "function" == typeof i.onError && (e = i.onError)
     }
-    return isScope(t) ? i = t : null === t ? i = null : "function" == typeof t && (e = t), {
-        scope: i,
+    return isScope(t) ? n = t : null === t ? n = null : "function" == typeof t && (e = t), {
+        scope: n,
         onError: e
     }
 }
 
 function mergeConfigs(...t) {
     const e = {};
-    for (const i of t)
-        for (const t of Object.keys(i)) {
-            const n = e[t],
-                s = i[t];
-            isObject(n) && isObject(s) ? e[t] = mergeConfigs(n, s) : e[t] = s
+    for (const n of t)
+        for (const t of Object.keys(n)) {
+            const i = e[t],
+                s = n[t];
+            isObject(i) && isObject(s) ? e[t] = mergeConfigs(i, s) : e[t] = s
         }
     return e
 }
 
-function extractConfigByNamespace(t, e, i) {
-    const n = t.properties[i];
-    if ("object" !== (null == n ? void 0 : n.type)) return;
+function extractConfigByNamespace(t, e, n) {
+    const i = t.properties[n];
+    if ("object" !== (null == i ? void 0 : i.type)) return;
     const s = {
-        [i]: {}
+        [n]: {}
     };
     for (const [o, r] of Object.entries(e)) {
         let t = s;
         const e = o.split(".");
-        for (const [n, s] of e.entries()) isObject(t) && (n < e.length - 1 ? (isObject(t[s]) || (t[s] = {}), t = t[s]) : o !== i && (t[s] = normaliseString(r)))
+        for (const [i, s] of e.entries()) isObject(t) && (i < e.length - 1 ? (isObject(t[s]) || (t[s] = {}), t = t[s]) : o !== n && (t[s] = normaliseString(r)))
     }
-    return s[i]
+    return s[n]
 }
 class I18n {
     constructor(t = {}, e = {}) {
-        var i;
-        this.translations = void 0, this.locale = void 0, this.translations = t, this.locale = null != (i = e.locale) ? i : document.documentElement.lang || "en"
+        var n;
+        this.translations = void 0, this.locale = void 0, this.translations = t, this.locale = null != (n = e.locale) ? n : document.documentElement.lang || "en"
     }
     t(t, e) {
         if (!t) throw new Error("i18n: lookup key missing");
-        let i = this.translations[t];
-        if ("number" == typeof(null == e ? void 0 : e.count) && isObject(i)) {
-            const n = i[this.getPluralSuffix(t, e.count)];
-            n && (i = n)
+        let n = this.translations[t];
+        if ("number" == typeof(null == e ? void 0 : e.count) && isObject(n)) {
+            const i = n[this.getPluralSuffix(t, e.count)];
+            i && (n = i)
         }
-        if ("string" == typeof i) {
-            if (i.match(/%{(.\S+)}/)) {
+        if ("string" == typeof n) {
+            if (n.match(/%{(.\S+)}/)) {
                 if (!e) throw new Error("i18n: cannot replace placeholders in string if no option data provided");
-                return this.replacePlaceholders(i, e)
+                return this.replacePlaceholders(n, e)
             }
-            return i
+            return n
         }
         return t
     }
     replacePlaceholders(t, e) {
-        const i = Intl.NumberFormat.supportedLocalesOf(this.locale).length ? new Intl.NumberFormat(this.locale) : void 0;
-        return t.replace(/%{(.\S+)}/g, (function(t, n) {
-            if (Object.prototype.hasOwnProperty.call(e, n)) {
-                const t = e[n];
-                return !1 === t || "number" != typeof t && "string" != typeof t ? "" : "number" == typeof t ? i ? i.format(t) : `${t}` : t
+        const n = Intl.NumberFormat.supportedLocalesOf(this.locale).length ? new Intl.NumberFormat(this.locale) : void 0;
+        return t.replace(/%{(.\S+)}/g, (function(t, i) {
+            if (Object.prototype.hasOwnProperty.call(e, i)) {
+                const t = e[i];
+                return !1 === t || "number" != typeof t && "string" != typeof t ? "" : "number" == typeof t ? n ? n.format(t) : `${t}` : t
             }
             throw new Error(`i18n: no data found to replace ${t} placeholder in string`)
         }))
@@ -222,11 +222,11 @@ class I18n {
     }
     getPluralSuffix(t, e) {
         if (e = Number(e), !isFinite(e)) return "other";
-        const i = this.translations[t],
-            n = this.hasIntlPluralRulesSupport() ? new Intl.PluralRules(this.locale).select(e) : "other";
-        if (isObject(i)) {
-            if (n in i) return n;
-            if ("other" in i) return console.warn(`i18n: Missing plural form ".${n}" for "${this.locale}" locale. Falling back to ".other".`), "other"
+        const n = this.translations[t],
+            i = this.hasIntlPluralRulesSupport() ? new Intl.PluralRules(this.locale).select(e) : "other";
+        if (isObject(n)) {
+            if (i in n) return i;
+            if ("other" in n) return console.warn(`i18n: Missing plural form ".${i}" for "${this.locale}" locale. Falling back to ".other".`), "other"
         }
         throw new Error(`i18n: Plural form ".other" is required for "${this.locale}" locale`)
     }
@@ -234,12 +234,12 @@ class I18n {
 class Accordion extends ConfigurableComponent {
     constructor(t, e = {}) {
         super(t, e), this.i18n = void 0, this.controlsClass = "govuk-accordion__controls", this.showAllClass = "govuk-accordion__show-all", this.showAllTextClass = "govuk-accordion__show-all-text", this.sectionClass = "govuk-accordion__section", this.sectionExpandedClass = "govuk-accordion__section--expanded", this.sectionButtonClass = "govuk-accordion__section-button", this.sectionHeaderClass = "govuk-accordion__section-header", this.sectionHeadingClass = "govuk-accordion__section-heading", this.sectionHeadingDividerClass = "govuk-accordion__section-heading-divider", this.sectionHeadingTextClass = "govuk-accordion__section-heading-text", this.sectionHeadingTextFocusClass = "govuk-accordion__section-heading-text-focus", this.sectionShowHideToggleClass = "govuk-accordion__section-toggle", this.sectionShowHideToggleFocusClass = "govuk-accordion__section-toggle-focus", this.sectionShowHideTextClass = "govuk-accordion__section-toggle-text", this.upChevronIconClass = "govuk-accordion-nav__chevron", this.downChevronIconClass = "govuk-accordion-nav__chevron--down", this.sectionSummaryClass = "govuk-accordion__section-summary", this.sectionSummaryFocusClass = "govuk-accordion__section-summary-focus", this.sectionContentClass = "govuk-accordion__section-content", this.$sections = void 0, this.$showAllButton = null, this.$showAllIcon = null, this.$showAllText = null, this.i18n = new I18n(this.config.i18n);
-        const i = this.$root.querySelectorAll(`.${this.sectionClass}`);
-        if (!i.length) throw new ElementError({
+        const n = this.$root.querySelectorAll(`.${this.sectionClass}`);
+        if (!n.length) throw new ElementError({
             component: Accordion,
             identifier: `Sections (\`<div class="${this.sectionClass}">\`)`
         });
-        this.$sections = i, this.initControls(), this.initSectionHeaders(), this.updateShowAllButton(this.areAllSectionsOpen())
+        this.$sections = n, this.initControls(), this.initSectionHeaders(), this.updateShowAllButton(this.areAllSectionsOpen())
     }
     initControls() {
         this.$showAllButton = document.createElement("button"), this.$showAllButton.setAttribute("type", "button"), this.$showAllButton.setAttribute("class", this.showAllClass), this.$showAllButton.setAttribute("aria-expanded", "false"), this.$showAllIcon = document.createElement("span"), this.$showAllIcon.classList.add(this.upChevronIconClass), this.$showAllButton.appendChild(this.$showAllIcon);
@@ -248,33 +248,33 @@ class Accordion extends ConfigurableComponent {
     }
     initSectionHeaders() {
         this.$sections.forEach(((t, e) => {
-            const i = t.querySelector(`.${this.sectionHeaderClass}`);
-            if (!i) throw new ElementError({
+            const n = t.querySelector(`.${this.sectionHeaderClass}`);
+            if (!n) throw new ElementError({
                 component: Accordion,
                 identifier: `Section headers (\`<div class="${this.sectionHeaderClass}">\`)`
             });
-            this.constructHeaderMarkup(i, e), this.setExpanded(this.isExpanded(t), t), i.addEventListener("click", (() => this.onSectionToggle(t))), this.setInitialState(t)
+            this.constructHeaderMarkup(n, e), this.setExpanded(this.isExpanded(t), t), n.addEventListener("click", (() => this.onSectionToggle(t))), this.setInitialState(t)
         }))
     }
     constructHeaderMarkup(t, e) {
-        const i = t.querySelector(`.${this.sectionButtonClass}`),
-            n = t.querySelector(`.${this.sectionHeadingClass}`),
+        const n = t.querySelector(`.${this.sectionButtonClass}`),
+            i = t.querySelector(`.${this.sectionHeadingClass}`),
             s = t.querySelector(`.${this.sectionSummaryClass}`);
-        if (!n) throw new ElementError({
+        if (!i) throw new ElementError({
             component: Accordion,
             identifier: `Section heading (\`.${this.sectionHeadingClass}\`)`
         });
-        if (!i) throw new ElementError({
+        if (!n) throw new ElementError({
             component: Accordion,
             identifier: `Section button placeholder (\`<span class="${this.sectionButtonClass}">\`)`
         });
         const o = document.createElement("button");
         o.setAttribute("type", "button"), o.setAttribute("aria-controls", `${this.$root.id}-content-${e+1}`);
-        for (const d of Array.from(i.attributes)) "id" !== d.name && o.setAttribute(d.name, d.value);
+        for (const d of Array.from(n.attributes)) "id" !== d.name && o.setAttribute(d.name, d.value);
         const r = document.createElement("span");
-        r.classList.add(this.sectionHeadingTextClass), r.id = i.id;
+        r.classList.add(this.sectionHeadingTextClass), r.id = n.id;
         const a = document.createElement("span");
-        a.classList.add(this.sectionHeadingTextFocusClass), r.appendChild(a), Array.from(i.childNodes).forEach((t => a.appendChild(t)));
+        a.classList.add(this.sectionHeadingTextFocusClass), r.appendChild(a), Array.from(n.childNodes).forEach((t => a.appendChild(t)));
         const l = document.createElement("span");
         l.classList.add(this.sectionShowHideToggleClass), l.setAttribute("data-nosnippet", "");
         const c = document.createElement("span");
@@ -285,16 +285,16 @@ class Accordion extends ConfigurableComponent {
             const t = document.createElement("span"),
                 e = document.createElement("span");
             e.classList.add(this.sectionSummaryFocusClass), t.appendChild(e);
-            for (const i of Array.from(s.attributes)) t.setAttribute(i.name, i.value);
+            for (const n of Array.from(s.attributes)) t.setAttribute(n.name, n.value);
             Array.from(s.childNodes).forEach((t => e.appendChild(t))), s.remove(), o.appendChild(t), o.appendChild(this.getButtonPunctuationEl())
         }
-        o.appendChild(l), n.removeChild(i), n.appendChild(o)
+        o.appendChild(l), i.removeChild(n), i.appendChild(o)
     }
     onBeforeMatch(t) {
         const e = t.target;
         if (!(e instanceof Element)) return;
-        const i = e.closest(`.${this.sectionClass}`);
-        i && this.setExpanded(!0, i)
+        const n = e.closest(`.${this.sectionClass}`);
+        n && this.setExpanded(!0, n)
     }
     onSectionToggle(t) {
         const e = !this.isExpanded(t);
@@ -307,24 +307,24 @@ class Accordion extends ConfigurableComponent {
         })), this.updateShowAllButton(t)
     }
     setExpanded(t, e) {
-        const i = e.querySelector(`.${this.upChevronIconClass}`),
-            n = e.querySelector(`.${this.sectionShowHideTextClass}`),
+        const n = e.querySelector(`.${this.upChevronIconClass}`),
+            i = e.querySelector(`.${this.sectionShowHideTextClass}`),
             s = e.querySelector(`.${this.sectionButtonClass}`),
             o = e.querySelector(`.${this.sectionContentClass}`);
         if (!o) throw new ElementError({
             component: Accordion,
             identifier: `Section content (\`<div class="${this.sectionContentClass}">\`)`
         });
-        if (!i || !n || !s) return;
+        if (!n || !i || !s) return;
         const r = t ? this.i18n.t("hideSection") : this.i18n.t("showSection");
-        n.textContent = r, s.setAttribute("aria-expanded", `${t}`);
+        i.textContent = r, s.setAttribute("aria-expanded", `${t}`);
         const a = [],
             l = e.querySelector(`.${this.sectionHeadingTextClass}`);
         l && a.push(l.textContent.trim());
         const c = e.querySelector(`.${this.sectionSummaryClass}`);
         c && a.push(c.textContent.trim());
         const u = t ? this.i18n.t("hideSectionAriaLabel") : this.i18n.t("showSectionAriaLabel");
-        a.push(u), s.setAttribute("aria-label", a.join(" , ")), t ? (o.removeAttribute("hidden"), e.classList.add(this.sectionExpandedClass), i.classList.remove(this.downChevronIconClass)) : (o.setAttribute("hidden", "until-found"), e.classList.remove(this.sectionExpandedClass), i.classList.add(this.downChevronIconClass)), this.updateShowAllButton(this.areAllSectionsOpen())
+        a.push(u), s.setAttribute("aria-label", a.join(" , ")), t ? (o.removeAttribute("hidden"), e.classList.add(this.sectionExpandedClass), n.classList.remove(this.downChevronIconClass)) : (o.setAttribute("hidden", "until-found"), e.classList.remove(this.sectionExpandedClass), n.classList.add(this.downChevronIconClass)), this.updateShowAllButton(this.areAllSectionsOpen())
     }
     isExpanded(t) {
         return t.classList.contains(this.sectionExpandedClass)
@@ -341,18 +341,18 @@ class Accordion extends ConfigurableComponent {
     }
     storeState(t, e) {
         if (!this.config.rememberExpanded) return;
-        const i = this.getIdentifier(t);
-        if (i) try {
-            window.sessionStorage.setItem(i, e.toString())
-        } catch (n) {}
+        const n = this.getIdentifier(t);
+        if (n) try {
+            window.sessionStorage.setItem(n, e.toString())
+        } catch (i) {}
     }
     setInitialState(t) {
         if (!this.config.rememberExpanded) return;
         const e = this.getIdentifier(t);
         if (e) try {
-            const i = window.sessionStorage.getItem(e);
-            null !== i && this.setExpanded("true" === i, t)
-        } catch (i) {}
+            const n = window.sessionStorage.getItem(e);
+            null !== n && this.setExpanded("true" === n, t)
+        } catch (n) {}
     }
     getButtonPunctuationEl() {
         const t = document.createElement("span");
@@ -395,8 +395,8 @@ class Button extends ConfigurableComponent {
 }
 
 function closestAttributeValue(t, e) {
-    const i = t.closest(`[${e}]`);
-    return i ? i.getAttribute(e) : null
+    const n = t.closest(`[${e}]`);
+    return n ? n.getAttribute(e) : null
 }
 Button.moduleName = "govuk-button", Button.defaults = Object.freeze({
     preventDoubleClick: !1
@@ -416,7 +416,7 @@ class CharacterCount extends ConfigurableComponent {
         }), e
     }
     constructor(t, e = {}) {
-        var i, n;
+        var n, i;
         super(t, e), this.$textarea = void 0, this.count = 0, this.$visibleCountMessage = void 0, this.$screenReaderCountMessage = void 0, this.lastInputTimestamp = null, this.lastInputValue = "", this.valueChecker = null, this.i18n = void 0, this.maxLength = void 0;
         const s = this.$root.querySelector(".govuk-js-character-count");
         if (!(s instanceof HTMLTextAreaElement || s instanceof HTMLInputElement)) throw new ElementError({
@@ -426,24 +426,24 @@ class CharacterCount extends ConfigurableComponent {
             identifier: "Form field (`.govuk-js-character-count`)"
         });
         const o = function(t, e) {
-            const i = [];
-            for (const [n, s] of Object.entries(t)) {
+            const n = [];
+            for (const [i, s] of Object.entries(t)) {
                 const t = [];
                 if (Array.isArray(s)) {
                     for (const {
-                            required: i,
-                            errorMessage: n
+                            required: n,
+                            errorMessage: i
                         }
-                        of s) i.every((t => !!e[t])) || t.push(n);
-                    "anyOf" !== n || s.length - t.length >= 1 || i.push(...t)
+                        of s) n.every((t => !!e[t])) || t.push(i);
+                    "anyOf" !== i || s.length - t.length >= 1 || n.push(...t)
                 }
             }
-            return i
+            return n
         }(CharacterCount.schema, this.config);
         if (o[0]) throw new ConfigError(formatErrorMessage(CharacterCount, o[0]));
         this.i18n = new I18n(this.config.i18n, {
             locale: closestAttributeValue(this.$root, "lang")
-        }), this.maxLength = null != (i = null != (n = this.config.maxwords) ? n : this.config.maxlength) ? i : 1 / 0, this.$textarea = s;
+        }), this.maxLength = null != (n = null != (i = this.config.maxwords) ? i : this.config.maxlength) ? n : 1 / 0, this.$textarea = s;
         const r = `${this.$textarea.id}-info`,
             a = document.getElementById(r);
         if (!a) throw new ElementError({
@@ -492,8 +492,8 @@ class CharacterCount extends ConfigurableComponent {
         const t = this.$textarea.value;
         if (this.config.maxwords) {
             var e;
-            const i = null != (e = t.match(/\S+/g)) ? e : [];
-            this.count = i.length
+            const n = null != (e = t.match(/\S+/g)) ? e : [];
+            this.count = n.length
         } else this.count = t.length
     }
     getCountMessage() {
@@ -503,8 +503,8 @@ class CharacterCount extends ConfigurableComponent {
     }
     formatCountMessage(t, e) {
         if (0 === t) return this.i18n.t(`${e}AtLimit`);
-        const i = t < 0 ? "OverLimit" : "UnderLimit";
-        return this.i18n.t(`${e}${i}`, {
+        const n = t < 0 ? "OverLimit" : "UnderLimit";
+        return this.i18n.t(`${e}${n}`, {
             count: Math.abs(t)
         })
     }
@@ -587,10 +587,10 @@ class Checkboxes extends Component {
     syncConditionalRevealWithInputState(t) {
         const e = t.getAttribute("aria-controls");
         if (!e) return;
-        const i = document.getElementById(e);
-        if (null != i && i.classList.contains("govuk-checkboxes__conditional")) {
+        const n = document.getElementById(e);
+        if (null != n && n.classList.contains("govuk-checkboxes__conditional")) {
             const e = t.checked;
-            t.setAttribute("aria-expanded", e.toString()), i.classList.toggle("govuk-checkboxes__conditional--hidden", !e)
+            t.setAttribute("aria-expanded", e.toString()), n.classList.toggle("govuk-checkboxes__conditional--hidden", !e)
         }
     }
     unCheckAllInputsExcept(t) {
@@ -623,25 +623,25 @@ class ErrorSummary extends ConfigurableComponent {
         if (!(t instanceof HTMLAnchorElement)) return !1;
         const e = t.hash.replace("#", "");
         if (!e) return !1;
-        const i = document.getElementById(e);
-        if (!i) return !1;
-        const n = this.getAssociatedLegendOrLabel(i);
-        return !!n && (n.scrollIntoView(), i.focus({
+        const n = document.getElementById(e);
+        if (!n) return !1;
+        const i = this.getAssociatedLegendOrLabel(n);
+        return !!i && (i.scrollIntoView(), n.focus({
             preventScroll: !0
         }), !0)
     }
     getAssociatedLegendOrLabel(t) {
         var e;
-        const i = t.closest("fieldset");
-        if (i) {
-            const e = i.getElementsByTagName("legend");
+        const n = t.closest("fieldset");
+        if (n) {
+            const e = n.getElementsByTagName("legend");
             if (e.length) {
-                const i = e[0];
-                if (t instanceof HTMLInputElement && ("checkbox" === t.type || "radio" === t.type)) return i;
-                const n = i.getBoundingClientRect().top,
+                const n = e[0];
+                if (t instanceof HTMLInputElement && ("checkbox" === t.type || "radio" === t.type)) return n;
+                const i = n.getBoundingClientRect().top,
                     s = t.getBoundingClientRect();
                 if (s.height && window.innerHeight) {
-                    if (s.top + s.height - n < window.innerHeight / 2) return i
+                    if (s.top + s.height - i < window.innerHeight / 2) return n
                 }
             }
         }
@@ -660,16 +660,16 @@ ErrorSummary.moduleName = "govuk-error-summary", ErrorSummary.defaults = Object.
 class ExitThisPage extends ConfigurableComponent {
     constructor(t, e = {}) {
         super(t, e), this.i18n = void 0, this.$button = void 0, this.$skiplinkButton = null, this.$updateSpan = null, this.$indicatorContainer = null, this.$overlay = null, this.keypressCounter = 0, this.lastKeyWasModified = !1, this.timeoutTime = 5e3, this.keypressTimeoutId = null, this.timeoutMessageId = null;
-        const i = this.$root.querySelector(".govuk-exit-this-page__button");
-        if (!(i instanceof HTMLAnchorElement)) throw new ElementError({
+        const n = this.$root.querySelector(".govuk-exit-this-page__button");
+        if (!(n instanceof HTMLAnchorElement)) throw new ElementError({
             component: ExitThisPage,
-            element: i,
+            element: n,
             expectedType: "HTMLAnchorElement",
             identifier: "Button (`.govuk-exit-this-page__button`)"
         });
-        this.i18n = new I18n(this.config.i18n), this.$button = i;
-        const n = document.querySelector(".govuk-js-exit-this-page-skiplink");
-        n instanceof HTMLAnchorElement && (this.$skiplinkButton = n), this.buildIndicator(), this.initUpdateSpan(), this.initButtonClickHandler(), "govukFrontendExitThisPageKeypress" in document.body.dataset || (document.addEventListener("keyup", this.handleKeypress.bind(this), !0), document.body.dataset.govukFrontendExitThisPageKeypress = "true"), window.addEventListener("pageshow", this.resetPage.bind(this))
+        this.i18n = new I18n(this.config.i18n), this.$button = n;
+        const i = document.querySelector(".govuk-js-exit-this-page-skiplink");
+        i instanceof HTMLAnchorElement && (this.$skiplinkButton = i), this.buildIndicator(), this.initUpdateSpan(), this.initButtonClickHandler(), "govukFrontendExitThisPageKeypress" in document.body.dataset || (document.addEventListener("keyup", this.handleKeypress.bind(this), !0), document.body.dataset.govukFrontendExitThisPageKeypress = "true"), window.addEventListener("pageshow", this.resetPage.bind(this))
     }
     initUpdateSpan() {
         this.$updateSpan = document.createElement("span"), this.$updateSpan.setAttribute("role", "status"), this.$updateSpan.className = "govuk-visually-hidden", this.$root.appendChild(this.$updateSpan)
@@ -733,21 +733,21 @@ ExitThisPage.moduleName = "govuk-exit-this-page", ExitThisPage.defaults = Object
 class FileUpload extends ConfigurableComponent {
     constructor(t, e = {}) {
         super(t, e), this.$input = void 0, this.$button = void 0, this.$status = void 0, this.$label = void 0, this.i18n = void 0, this.id = void 0, this.$announcements = void 0, this.enteredAnotherElement = void 0;
-        const i = this.$root.querySelector("input");
-        if (null === i) throw new ElementError({
+        const n = this.$root.querySelector("input");
+        if (null === n) throw new ElementError({
             component: FileUpload,
             identifier: 'File inputs (`<input type="file">`)'
         });
-        if ("file" !== i.type) throw new ElementError(formatErrorMessage(FileUpload, 'File input (`<input type="file">`) attribute (`type`) is not `file`'));
-        if (this.$input = i, !this.$input.id) throw new ElementError({
+        if ("file" !== n.type) throw new ElementError(formatErrorMessage(FileUpload, 'File input (`<input type="file">`) attribute (`type`) is not `file`'));
+        if (this.$input = n, !this.$input.id) throw new ElementError({
             component: FileUpload,
             identifier: 'File input (`<input type="file">`) attribute (`id`)'
         });
         this.id = this.$input.id, this.i18n = new I18n(this.config.i18n, {
             locale: closestAttributeValue(this.$root, "lang")
         });
-        const n = this.findLabel();
-        n.id || (n.id = `${this.id}-label`), this.$label = n, this.$input.id = `${this.id}-input`, this.$input.setAttribute("hidden", "hidden"), this.$status = this.createStatus(), this.$button = this.createButton(), this.$root.insertAdjacentElement("afterbegin", this.$button), this.$input.addEventListener("change", this.onChange.bind(this)), this.updateDisabledState(), this.observeDisabledState(), this.$announcements = document.createElement("span"), this.$announcements.classList.add("govuk-file-upload-announcements"), this.$announcements.classList.add("govuk-visually-hidden"), this.$announcements.setAttribute("aria-live", "assertive"), this.$root.insertAdjacentElement("afterend", this.$announcements), this.bindDraggingEvents()
+        const i = this.findLabel();
+        i.id || (i.id = `${this.id}-label`), this.$label = i, this.$input.id = `${this.id}-input`, this.$input.setAttribute("hidden", "hidden"), this.$status = this.createStatus(), this.$button = this.createButton(), this.$root.insertAdjacentElement("afterbegin", this.$button), this.$input.addEventListener("change", this.onChange.bind(this)), this.updateDisabledState(), this.observeDisabledState(), this.$announcements = document.createElement("span"), this.$announcements.classList.add("govuk-file-upload-announcements"), this.$announcements.classList.add("govuk-visually-hidden"), this.$announcements.setAttribute("aria-live", "assertive"), this.$root.insertAdjacentElement("afterend", this.$announcements), this.bindDraggingEvents()
     }
     createStatus() {
         const t = document.createElement("span");
@@ -758,14 +758,14 @@ class FileUpload extends ConfigurableComponent {
         t.classList.add("govuk-file-upload-button"), t.type = "button", t.id = this.id, t.classList.add("govuk-file-upload-button--empty");
         const e = this.$input.getAttribute("aria-describedby");
         e && t.setAttribute("aria-describedby", e), t.appendChild(this.$status);
-        const i = document.createElement("span");
-        i.className = "govuk-visually-hidden", i.innerText = ", ", i.id = `${this.id}-comma`, t.appendChild(i);
         const n = document.createElement("span");
-        n.className = "govuk-file-upload-button__pseudo-button-container";
+        n.className = "govuk-visually-hidden", n.innerText = ", ", n.id = `${this.id}-comma`, t.appendChild(n);
+        const i = document.createElement("span");
+        i.className = "govuk-file-upload-button__pseudo-button-container";
         const s = document.createElement("span");
-        s.className = "govuk-button govuk-button--secondary govuk-file-upload-button__pseudo-button", s.innerText = this.i18n.t("chooseFilesButton"), n.appendChild(s), n.insertAdjacentText("beforeend", " ");
+        s.className = "govuk-button govuk-button--secondary govuk-file-upload-button__pseudo-button", s.innerText = this.i18n.t("chooseFilesButton"), i.appendChild(s), i.insertAdjacentText("beforeend", " ");
         const o = document.createElement("span");
-        return o.className = "govuk-body govuk-file-upload-button__instruction", o.innerText = this.i18n.t("dropInstruction"), n.appendChild(o), t.appendChild(n), t.setAttribute("aria-labelledby", `${this.$label.id} ${i.id} ${t.id}`), t.addEventListener("click", this.onClick.bind(this)), t.addEventListener("dragover", (t => {
+        return o.className = "govuk-body govuk-file-upload-button__instruction", o.innerText = this.i18n.t("dropInstruction"), i.appendChild(o), t.appendChild(i), t.setAttribute("aria-labelledby", `${this.$label.id} ${n.id} ${t.id}`), t.addEventListener("click", this.onClick.bind(this)), t.addEventListener("dragover", (t => {
             t.preventDefault()
         })), t
     }
@@ -794,7 +794,7 @@ class FileUpload extends ConfigurableComponent {
     canDrop(t) {
         return t.items.length ? this.matchesInputCapacity(function(t) {
             let e = 0;
-            for (let i = 0; i < t.length; i++) "file" === t[i].kind && e++;
+            for (let n = 0; n < t.length; n++) "file" === t[n].kind && e++;
             return e
         }(t.items)) : !t.types.length || t.types.includes("Files")
     }
@@ -848,6 +848,58 @@ FileUpload.moduleName = "govuk-file-upload", FileUpload.defaults = Object.freeze
         }
     }
 });
+class LanguageSwitcher extends Component {
+    constructor(t) {
+        super(t), this.controlledMenus = [], this.mql = null;
+        const e = this.$root.querySelector(".govuk-js-language-switcher-toggle");
+        if (!e) return this;
+        const n = e.getAttribute("aria-controls");
+        if (!n) throw new ElementError({
+            component: LanguageSwitcher,
+            identifier: 'Language switcher button (`<button class="govuk-js-language-switcher-toggle">`) attribute (`aria-controls`)'
+        });
+        const i = document.getElementById(n);
+        if (!i) throw new ElementError({
+            component: LanguageSwitcher,
+            element: i,
+            identifier: `Language switcher list (\`<ul id="${n}">\`)`
+        });
+        this.controlledMenus = [{
+            $menu: i,
+            $menuButton: e,
+            menuIsOpen: !1
+        }], this.setupResponsiveChecks();
+        for (const s of this.controlledMenus) s.$menuButton.addEventListener("click", (() => this.handleMenuButtonClick(s)))
+    }
+    setupResponsiveChecks() {
+        const t = getBreakpoint("tablet");
+        if (!t.value) throw new ElementError({
+            component: LanguageSwitcher,
+            identifier: `CSS custom property (\`${t.property}\`) on pseudo-class \`:root\``
+        });
+        this.mql = window.matchMedia(`(min-width: ${t.value})`), "addEventListener" in this.mql ? this.mql.addEventListener("change", (() => this.checkMode())) : this.mql.addListener((() => this.checkMode())), this.checkMode()
+    }
+    checkMode() {
+        if (this.mql)
+            for (const t of this.controlledMenus) this.mql.matches ? (t.$menu.removeAttribute("hidden"), setAttributes$1(t.$menuButton, e)) : (removeAttributes$1(t.$menuButton, Object.keys(e)), t.$menuButton.setAttribute("aria-expanded", t.menuIsOpen.toString()), t.menuIsOpen ? t.$menu.removeAttribute("hidden") : t.$menu.setAttribute("hidden", ""))
+    }
+    handleMenuButtonClick(t) {
+        t.menuIsOpen = !t.menuIsOpen, this.checkMode()
+    }
+}
+LanguageSwitcher.moduleName = "govuk-language-switcher";
+const e = {
+    hidden: "",
+    "aria-hidden": "true"
+};
+
+function setAttributes$1(t, e) {
+    for (const n in e) t.setAttribute(n, e[n])
+}
+
+function removeAttributes$1(t, e) {
+    for (const n of e) t.removeAttribute(n)
+}
 class NotificationBanner extends ConfigurableComponent {
     constructor(t, e = {}) {
         super(t, e), "alert" !== this.$root.getAttribute("role") || this.config.disableAutoFocus || setFocus(this.$root)
@@ -865,23 +917,23 @@ NotificationBanner.moduleName = "govuk-notification-banner", NotificationBanner.
 class PasswordInput extends ConfigurableComponent {
     constructor(t, e = {}) {
         super(t, e), this.i18n = void 0, this.$input = void 0, this.$showHideButton = void 0, this.$screenReaderStatusMessage = void 0;
-        const i = this.$root.querySelector(".govuk-js-password-input-input");
-        if (!(i instanceof HTMLInputElement)) throw new ElementError({
+        const n = this.$root.querySelector(".govuk-js-password-input-input");
+        if (!(n instanceof HTMLInputElement)) throw new ElementError({
             component: PasswordInput,
-            element: i,
+            element: n,
             expectedType: "HTMLInputElement",
             identifier: "Form field (`.govuk-js-password-input-input`)"
         });
-        if ("password" !== i.type) throw new ElementError("Password input: Form field (`.govuk-js-password-input-input`) must be of type `password`.");
-        const n = this.$root.querySelector(".govuk-js-password-input-toggle");
-        if (!(n instanceof HTMLButtonElement)) throw new ElementError({
+        if ("password" !== n.type) throw new ElementError("Password input: Form field (`.govuk-js-password-input-input`) must be of type `password`.");
+        const i = this.$root.querySelector(".govuk-js-password-input-toggle");
+        if (!(i instanceof HTMLButtonElement)) throw new ElementError({
             component: PasswordInput,
-            element: n,
+            element: i,
             expectedType: "HTMLButtonElement",
             identifier: "Button (`.govuk-js-password-input-toggle`)"
         });
-        if ("button" !== n.type) throw new ElementError("Password input: Button (`.govuk-js-password-input-toggle`) must be of type `button`.");
-        this.$input = i, this.$showHideButton = n, this.i18n = new I18n(this.config.i18n, {
+        if ("button" !== i.type) throw new ElementError("Password input: Button (`.govuk-js-password-input-toggle`) must be of type `button`.");
+        this.$input = n, this.$showHideButton = i, this.i18n = new I18n(this.config.i18n, {
             locale: closestAttributeValue(this.$root, "lang")
         }), this.$showHideButton.removeAttribute("hidden");
         const s = document.createElement("div");
@@ -902,9 +954,9 @@ class PasswordInput extends ConfigurableComponent {
         if (t === this.$input.type) return;
         this.$input.setAttribute("type", t);
         const e = "password" === t,
-            i = e ? "show" : "hide",
-            n = e ? "passwordHidden" : "passwordShown";
-        this.$showHideButton.innerText = this.i18n.t(`${i}Password`), this.$showHideButton.setAttribute("aria-label", this.i18n.t(`${i}PasswordAriaLabel`)), this.$screenReaderStatusMessage.innerText = this.i18n.t(`${n}Announcement`)
+            n = e ? "show" : "hide",
+            i = e ? "passwordHidden" : "passwordShown";
+        this.$showHideButton.innerText = this.i18n.t(`${n}Password`), this.$showHideButton.setAttribute("aria-label", this.i18n.t(`${n}PasswordAriaLabel`)), this.$screenReaderStatusMessage.innerText = this.i18n.t(`${i}Announcement`)
     }
 }
 PasswordInput.moduleName = "govuk-password-input", PasswordInput.defaults = Object.freeze({
@@ -948,20 +1000,20 @@ class Radios extends Component {
     syncConditionalRevealWithInputState(t) {
         const e = t.getAttribute("aria-controls");
         if (!e) return;
-        const i = document.getElementById(e);
-        if (null != i && i.classList.contains("govuk-radios__conditional")) {
+        const n = document.getElementById(e);
+        if (null != n && n.classList.contains("govuk-radios__conditional")) {
             const e = t.checked;
-            t.setAttribute("aria-expanded", e.toString()), i.classList.toggle("govuk-radios__conditional--hidden", !e)
+            t.setAttribute("aria-expanded", e.toString()), n.classList.toggle("govuk-radios__conditional--hidden", !e)
         }
     }
     handleClick(t) {
         const e = t.target;
         if (!(e instanceof HTMLInputElement) || "radio" !== e.type) return;
-        const i = document.querySelectorAll('input[type="radio"][aria-controls]'),
-            n = e.form,
+        const n = document.querySelectorAll('input[type="radio"][aria-controls]'),
+            i = e.form,
             s = e.name;
-        i.forEach((t => {
-            const e = t.form === n;
+        n.forEach((t => {
+            const e = t.form === i;
             t.name === s && e && this.syncConditionalRevealWithInputState(t)
         }))
     }
@@ -969,21 +1021,28 @@ class Radios extends Component {
 Radios.moduleName = "govuk-radios";
 class ServiceNavigation extends Component {
     constructor(t) {
-        super(t), this.$menuButton = void 0, this.$menu = void 0, this.menuIsOpen = !1, this.mql = null;
-        const e = this.$root.querySelector(".govuk-js-service-navigation-toggle");
-        if (!e) return this;
-        const i = e.getAttribute("aria-controls");
-        if (!i) throw new ElementError({
-            component: ServiceNavigation,
-            identifier: 'Navigation button (`<button class="govuk-js-service-navigation-toggle">`) attribute (`aria-controls`)'
-        });
-        const n = document.getElementById(i);
-        if (!n) throw new ElementError({
-            component: ServiceNavigation,
-            element: n,
-            identifier: `Navigation (\`<ul id="${i}">\`)`
-        });
-        this.$menu = n, this.$menuButton = e, this.setupResponsiveChecks(), this.$menuButton.addEventListener("click", (() => this.handleMenuButtonClick()))
+        super(t), this.controlledMenus = [], this.mql = null;
+        const e = this.$root.querySelectorAll(".govuk-js-service-navigation-toggle");
+        if (0 === e.length) return this;
+        this.controlledMenus = Array.from(e).map((t => {
+            const e = t.getAttribute("aria-controls");
+            if (!e) throw new ElementError({
+                component: ServiceNavigation,
+                identifier: 'Navigation button (`<button class="govuk-js-service-navigation-toggle">`) attribute (`aria-controls`)'
+            });
+            const n = document.getElementById(e);
+            if (!n) throw new ElementError({
+                component: ServiceNavigation,
+                element: n,
+                identifier: `Navigation (\`<ul id="${e}">\`)`
+            });
+            return {
+                $menu: n,
+                $menuButton: t,
+                menuIsOpen: !1
+            }
+        })), this.setupResponsiveChecks();
+        for (const n of this.controlledMenus) n.$menuButton.addEventListener("click", (() => this.handleMenuButtonClick(n)))
     }
     setupResponsiveChecks() {
         const t = getBreakpoint("tablet");
@@ -994,30 +1053,35 @@ class ServiceNavigation extends Component {
         this.mql = window.matchMedia(`(min-width: ${t.value})`), "addEventListener" in this.mql ? this.mql.addEventListener("change", (() => this.checkMode())) : this.mql.addListener((() => this.checkMode())), this.checkMode()
     }
     checkMode() {
-        this.mql && this.$menu && this.$menuButton && (this.mql.matches ? (this.$menu.removeAttribute("hidden"), function(t, e) {
-            for (const i in e) t.setAttribute(i, e[i])
-        }(this.$menuButton, e)) : (! function(t, e) {
-            for (const i of e) t.removeAttribute(i)
-        }(this.$menuButton, Object.keys(e)), this.$menuButton.setAttribute("aria-expanded", this.menuIsOpen.toString()), this.menuIsOpen ? this.$menu.removeAttribute("hidden") : this.$menu.setAttribute("hidden", "")))
+        if (this.mql)
+            for (const t of this.controlledMenus) this.mql.matches ? (t.$menu.removeAttribute("hidden"), setAttributes(t.$menuButton, n)) : (removeAttributes(t.$menuButton, Object.keys(n)), t.$menuButton.setAttribute("aria-expanded", t.menuIsOpen.toString()), t.menuIsOpen ? t.$menu.removeAttribute("hidden") : t.$menu.setAttribute("hidden", ""))
     }
-    handleMenuButtonClick() {
-        this.menuIsOpen = !this.menuIsOpen, this.checkMode()
+    handleMenuButtonClick(t) {
+        t.menuIsOpen = !t.menuIsOpen, this.checkMode()
     }
 }
 ServiceNavigation.moduleName = "govuk-service-navigation";
-const e = {
+const n = {
     hidden: "",
     "aria-hidden": "true"
 };
+
+function setAttributes(t, e) {
+    for (const n in e) t.setAttribute(n, e[n])
+}
+
+function removeAttributes(t, e) {
+    for (const n of e) t.removeAttribute(n)
+}
 class SkipLink extends Component {
     constructor(t) {
         var e;
         super(t);
-        const i = this.$root.hash,
-            n = null != (e = this.$root.getAttribute("href")) ? e : "";
+        const n = this.$root.hash,
+            i = null != (e = this.$root.getAttribute("href")) ? e : "";
         if (this.$root.origin !== window.location.origin || this.$root.pathname !== window.location.pathname) return;
-        const s = i.replace("#", "");
-        if (!s) throw new ElementError(`Skip link: Target link (\`href="${n}"\`) has no hash fragment`);
+        const s = n.replace("#", "");
+        if (!s) throw new ElementError(`Skip link: Target link (\`href="${i}"\`) has no hash fragment`);
         const o = document.getElementById(s);
         if (!o) throw new ElementError({
             component: SkipLink,
@@ -1044,17 +1108,17 @@ class Tabs extends Component {
             identifier: 'Links (`<a class="govuk-tabs__tab">`)'
         });
         this.$tabs = e, this.boundTabClick = this.onTabClick.bind(this), this.boundTabKeydown = this.onTabKeydown.bind(this), this.boundOnHashChange = this.onHashChange.bind(this);
-        const i = this.$root.querySelector(".govuk-tabs__list"),
-            n = this.$root.querySelectorAll("li.govuk-tabs__list-item");
-        if (!i) throw new ElementError({
+        const n = this.$root.querySelector(".govuk-tabs__list"),
+            i = this.$root.querySelectorAll("li.govuk-tabs__list-item");
+        if (!n) throw new ElementError({
             component: Tabs,
             identifier: 'List (`<ul class="govuk-tabs__list">`)'
         });
-        if (!n.length) throw new ElementError({
+        if (!i.length) throw new ElementError({
             component: Tabs,
             identifier: 'List items (`<li class="govuk-tabs__list-item">`)'
         });
-        this.$tabList = i, this.$tabListItems = n, this.setupResponsiveChecks()
+        this.$tabList = n, this.$tabListItems = i, this.setupResponsiveChecks()
     }
     setupResponsiveChecks() {
         const t = getBreakpoint("tablet");
@@ -1090,8 +1154,8 @@ class Tabs extends Component {
             e = this.getTab(t);
         if (!e) return;
         if (this.changingHash) return void(this.changingHash = !1);
-        const i = this.getCurrentTab();
-        i && (this.hideTab(i), this.showTab(e), e.focus())
+        const n = this.getCurrentTab();
+        n && (this.hideTab(n), this.showTab(e), e.focus())
     }
     hideTab(t) {
         this.unhighlightTab(t), this.hidePanel(t)
@@ -1106,8 +1170,8 @@ class Tabs extends Component {
         const e = t.hash.replace("#", "");
         if (!e) return;
         t.setAttribute("id", `tab_${e}`), t.setAttribute("role", "tab"), t.setAttribute("aria-controls", e), t.setAttribute("aria-selected", "false"), t.setAttribute("tabindex", "-1");
-        const i = this.getPanel(t);
-        i && (i.setAttribute("role", "tabpanel"), i.setAttribute("aria-labelledby", t.id), i.classList.add(this.jsHiddenClass))
+        const n = this.getPanel(t);
+        n && (n.setAttribute("role", "tabpanel"), n.setAttribute("aria-labelledby", t.id), n.classList.add(this.jsHiddenClass))
     }
     unsetAttributes(t) {
         t.removeAttribute("id"), t.removeAttribute("role"), t.removeAttribute("aria-controls"), t.removeAttribute("aria-selected"), t.removeAttribute("tabindex");
@@ -1116,14 +1180,14 @@ class Tabs extends Component {
     }
     onTabClick(t) {
         const e = this.getCurrentTab(),
-            i = t.currentTarget;
-        e && i instanceof HTMLAnchorElement && (t.preventDefault(), this.hideTab(e), this.showTab(i), this.createHistoryEntry(i))
+            n = t.currentTarget;
+        e && n instanceof HTMLAnchorElement && (t.preventDefault(), this.hideTab(e), this.showTab(n), this.createHistoryEntry(n))
     }
     createHistoryEntry(t) {
         const e = this.getPanel(t);
         if (!e) return;
-        const i = e.id;
-        e.id = "", this.changingHash = !0, window.location.hash = i, e.id = i
+        const n = e.id;
+        e.id = "", this.changingHash = !0, window.location.hash = n, e.id = n
     }
     onTabKeydown(t) {
         switch (t.key) {
@@ -1141,16 +1205,16 @@ class Tabs extends Component {
         if (null == t || !t.parentElement) return;
         const e = t.parentElement.nextElementSibling;
         if (!e) return;
-        const i = e.querySelector("a.govuk-tabs__tab");
-        i && (this.hideTab(t), this.showTab(i), i.focus(), this.createHistoryEntry(i))
+        const n = e.querySelector("a.govuk-tabs__tab");
+        n && (this.hideTab(t), this.showTab(n), n.focus(), this.createHistoryEntry(n))
     }
     activatePreviousTab() {
         const t = this.getCurrentTab();
         if (null == t || !t.parentElement) return;
         const e = t.parentElement.previousElementSibling;
         if (!e) return;
-        const i = e.querySelector("a.govuk-tabs__tab");
-        i && (this.hideTab(t), this.showTab(i), i.focus(), this.createHistoryEntry(i))
+        const n = e.querySelector("a.govuk-tabs__tab");
+        n && (this.hideTab(t), this.showTab(n), n.focus(), this.createHistoryEntry(n))
     }
     getPanel(t) {
         const e = t.hash.replace("#", "");
@@ -1177,17 +1241,17 @@ class Tabs extends Component {
 
 function initAll(t = {}) {
     const e = isObject(t) ? t : {},
-        i = normaliseOptions(t);
+        n = normaliseOptions(t);
     try {
         if (!isSupported()) throw new SupportError;
-        if (null === i.scope) throw new ElementError({
-            element: i.scope,
+        if (null === n.scope) throw new ElementError({
+            element: n.scope,
             identifier: "GOV.UK Frontend scope element (`$scope`)"
         })
-    } catch (n) {
-        return void(i.onError ? i.onError(n, {
+    } catch (i) {
+        return void(n.onError ? n.onError(i, {
             config: e
-        }) : console.log(n))
+        }) : console.log(i))
     } [
         [Accordion, e.accordion],
         [Button, e.button],
@@ -1196,6 +1260,7 @@ function initAll(t = {}) {
         [ErrorSummary, e.errorSummary],
         [ExitThisPage, e.exitThisPage],
         [FileUpload, e.fileUpload],
+        [LanguageSwitcher],
         [NotificationBanner, e.notificationBanner],
         [PasswordInput, e.passwordInput],
         [Radios],
@@ -1203,33 +1268,33 @@ function initAll(t = {}) {
         [SkipLink],
         [Tabs]
     ].forEach((([Component, t]) => {
-        createAll(Component, t, i)
+        createAll(Component, t, n)
     }))
 }
 
 function createAll(Component, t, e) {
-    let i;
-    const n = normaliseOptions(e);
+    let n;
+    const i = normaliseOptions(e);
     try {
         var s;
         if (!isSupported()) throw new SupportError;
-        if (null === n.scope) throw new ElementError({
-            element: n.scope,
+        if (null === i.scope) throw new ElementError({
+            element: i.scope,
             component: Component,
             identifier: "Scope element (`$scope`)"
         });
-        i = null == (s = n.scope) ? void 0 : s.querySelectorAll(`[data-module="${Component.moduleName}"]`)
+        n = null == (s = i.scope) ? void 0 : s.querySelectorAll(`[data-module="${Component.moduleName}"]`)
     } catch (o) {
-        return n.onError ? n.onError(o, {
+        return i.onError ? i.onError(o, {
             component: Component,
             config: t
         }) : console.log(o), []
     }
-    return Array.from(null != i ? i : []).map((e => {
+    return Array.from(null != n ? n : []).map((e => {
         try {
             return void 0 !== t ? new Component(e, t) : new Component(e)
         } catch (o) {
-            return n.onError ? n.onError(o, {
+            return i.onError ? i.onError(o, {
                 element: e,
                 component: Component,
                 config: t
@@ -1248,6 +1313,7 @@ export {
     ErrorSummary,
     ExitThisPage,
     FileUpload,
+    LanguageSwitcher,
     NotificationBanner,
     PasswordInput,
     Radios,

Action run for 4f519a7

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown

Stylesheets changes to npm package

diff --git a/packages/govuk-frontend/dist/govuk/govuk-frontend.min.css b/packages/govuk-frontend/dist/govuk/govuk-frontend.min.css
index db7d8ec3c..00128f6ee 100644
--- a/packages/govuk-frontend/dist/govuk/govuk-frontend.min.css
+++ b/packages/govuk-frontend/dist/govuk/govuk-frontend.min.css
@@ -3537,12 +3537,47 @@ screen and (forced-colors:active) {
     padding: 0 15px
 }
 
+.govuk-header__container--with-secondary {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    gap: 15px
+}
+
 .govuk-header__logo {
     box-sizing: border-box;
     padding-top: 16px;
     padding-bottom: 12px
 }
 
+.govuk-header__secondary {
+    margin-left: auto
+}
+
+.govuk-header__secondary .govuk-language-switcher {
+    margin: 0;
+    color: #fff
+}
+
+.govuk-header__secondary .govuk-language-switcher__link:link,
+.govuk-header__secondary .govuk-language-switcher__link:visited {
+    color: #fff
+}
+
+.govuk-header__secondary .govuk-language-switcher__link:focus {
+    color: var(--govuk-focus-text-colour, #0b0c0c)
+}
+
+.govuk-header__secondary .govuk-language-switcher__toggle {
+    margin: 0;
+    color: inherit
+}
+
+.govuk-header__secondary .govuk-language-switcher--right-align,
+.govuk-header__secondary .govuk-language-switcher-right {
+    margin: 0
+}
+
 .govuk-header__homepage-link {
     display: inline;
     margin-right: 10px;
@@ -3704,6 +3739,140 @@ screen and (forced-colors:active) {
     margin-bottom: 0
 }
 
+.govuk-language-switcher__toggle {
+    font-family: GDS Transport, arial, sans-serif;
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale;
+    font-weight: 700;
+    font-size: 1.1875rem;
+    line-height: 1.3157894737;
+    display: inline-flex;
+    align-items: center;
+    margin: 10px 0;
+    padding: 0;
+    border: 0;
+    color: var(--govuk-link-colour, #1a65a6);
+    background: none;
+    word-break: break-all;
+    cursor: pointer
+}
+
+@media print {
+    .govuk-language-switcher__toggle {
+        font-family: sans-serif;
+        font-size: 14pt;
+        line-height: 1.15
+    }
+}
+
+.govuk-language-switcher__toggle:focus {
+    outline: 3px solid transparent;
+    color: var(--govuk-focus-text-colour, #0b0c0c);
+    background-color: var(--govuk-focus-colour, #fd0);
+    box-shadow: 0 -2px var(--govuk-focus-colour, #fd0), 0 4px var(--govuk-focus-text-colour, #0b0c0c);
+    text-decoration: none
+}
+
+@supports not (text-wrap:balance) {
+    .govuk-language-switcher__toggle:focus {
+        -webkit-box-decoration-break: clone;
+        box-decoration-break: clone
+    }
+}
+
+.govuk-language-switcher__toggle:after {
+    display: inline-block;
+    width: 0;
+    height: 0;
+    -webkit-clip-path: polygon(0 0, 50% 100%, 100% 0);
+    clip-path: polygon(0 0, 50% 100%, 100% 0);
+    border-color: transparent;
+    border-style: solid;
+    border-width: 8.66px 5px 0;
+    border-top-color: inherit;
+    content: "";
+    margin-left: 5px
+}
+
+.govuk-language-switcher__toggle[aria-expanded=true]:after {
+    display: inline-block;
+    width: 0;
+    height: 0;
+    -webkit-clip-path: polygon(50% 0, 0 100%, 100% 100%);
+    clip-path: polygon(50% 0, 0 100%, 100% 100%);
+    border-color: transparent;
+    border-style: solid;
+    border-width: 0 5px 8.66px;
+    border-bottom-color: inherit
+}
+
+.govuk-language-switcher__toggle[hidden] {
+    display: none
+}
+
+@media (max-width:40.0525em) {
+
+    .govuk-language-switcher--post-end .govuk-language-switcher__item,
+    .govuk-language-switcher-end .govuk-language-switcher__item,
+    .govuk-language-switcher-responsive .govuk-language-switcher__item {
+        padding-bottom: 10px
+    }
+}
+
+@media (min-width:40.0625em) {
+
+    .govuk-language-switcher--post-end .govuk-language-switcher__item,
+    .govuk-language-switcher-end .govuk-language-switcher__item,
+    .govuk-language-switcher-responsive .govuk-language-switcher__item {
+        padding-top: 0;
+        line-height: 1
+    }
+
+    .govuk-language-switcher--post-end .govuk-language-switcher__item:not(:first-child):before,
+    .govuk-language-switcher-end .govuk-language-switcher__item:not(:first-child):before,
+    .govuk-language-switcher-responsive .govuk-language-switcher__item:not(:first-child):before {
+        top: 0;
+        transform: none
+    }
+}
+
+.govuk-language-switcher--collapsible .govuk-language-switcher__toggle,
+.govuk-language-switcher-responsive .govuk-language-switcher__toggle {
+    margin-bottom: 0
+}
+
+@media (max-width:40.0525em) {
+
+    .govuk-language-switcher--collapsible .govuk-language-switcher__list,
+    .govuk-language-switcher-responsive .govuk-language-switcher__list {
+        display: block;
+        margin-bottom: 15px
+    }
+
+    .govuk-language-switcher--collapsible .govuk-language-switcher__list[hidden],
+    .govuk-language-switcher-responsive .govuk-language-switcher__list[hidden] {
+        display: none
+    }
+
+    .govuk-language-switcher--collapsible .govuk-language-switcher__item,
+    .govuk-language-switcher-responsive .govuk-language-switcher__item {
+        margin: 10px 0
+    }
+
+    .govuk-language-switcher--collapsible .govuk-language-switcher__item:not(:first-child),
+    .govuk-language-switcher-responsive .govuk-language-switcher__item:not(:first-child) {
+        margin-left: 0;
+        padding-left: 0
+    }
+
+    .govuk-language-switcher--collapsible .govuk-language-switcher__item--icon,
+    .govuk-language-switcher--collapsible .govuk-language-switcher__item:not(:first-child):before,
+    .govuk-language-switcher-responsive .govuk-language-switcher__item--icon,
+    .govuk-language-switcher-responsive .govuk-language-switcher__item:not(:first-child):before {
+        display: none
+    }
+}
+
 .govuk-notification-banner {
     font-family: GDS Transport, arial, sans-serif;
     -webkit-font-smoothing: antialiased;
@@ -4800,6 +4969,214 @@ screen and (forced-colors:active) {
     flex-grow: 1
 }
 
+.govuk-language-switcher {
+    font-family: GDS Transport, arial, sans-serif;
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale;
+    font-weight: 400;
+    font-size: 1.1875rem;
+    line-height: 1.3157894737
+}
+
+@media print {
+    .govuk-language-switcher {
+        font-family: sans-serif;
+        font-size: 14pt;
+        line-height: 1.15
+    }
+}
+
+.govuk-language-switcher--right-align,
+.govuk-language-switcher-right {
+    margin: 10px 0
+}
+
+@media (min-width:40.0625em) {
+
+    .govuk-language-switcher--right-align,
+    .govuk-language-switcher-right {
+        margin: 0 0 0 auto
+    }
+}
+
+.govuk-language-switcher__list {
+    display: flex;
+    flex-wrap: wrap;
+    margin: 0;
+    padding: 0;
+    list-style: none
+}
+
+.govuk-language-switcher__item {
+    margin: 0;
+    padding: 0
+}
+
+.govuk-language-switcher__item:not(:first-child) {
+    position: relative;
+    margin-left: 10px;
+    padding-left: 10px
+}
+
+.govuk-language-switcher__item:not(:first-child):before {
+    content: "";
+    position: absolute;
+    top: 50%;
+    left: 0;
+    height: 1em;
+    transform: translateY(-50%);
+    border-left: 1px solid
+}
+
+@media (min-width:40.0625em) {
+    .govuk-language-switcher__item {
+        display: inline-block;
+        margin-top: 0;
+        margin-bottom: 0;
+        padding: 15px 0;
+        line-height: 1.5263157895
+    }
+}
+
+.govuk-language-switcher__icon {
+    display: inline-flex;
+    align-items: center;
+    filter: grayscale(1);
+    line-height: 1;
+    vertical-align: text-top
+}
+
+.govuk-language-switcher__icon-svg {
+    display: block
+}
+
+.govuk-language-switcher__toggle .govuk-language-switcher__icon {
+    margin-right: 5px
+}
+
+.govuk-language-switcher__item--icon+.govuk-language-switcher__item {
+    margin-left: 5px;
+    padding-left: 0
+}
+
+.govuk-language-switcher__item--icon+.govuk-language-switcher__item:before {
+    display: none
+}
+
+@media (max-width:40.0525em) {
+
+    .govuk-language-switcher-end .govuk-language-switcher__item,
+    .govuk-language-switcher-responsive .govuk-language-switcher__item {
+        padding-bottom: 10px
+    }
+}
+
+@media (min-width:40.0625em) {
+
+    .govuk-language-switcher-end .govuk-language-switcher__item,
+    .govuk-language-switcher-responsive .govuk-language-switcher__item {
+        padding-top: 0;
+        line-height: 1
+    }
+
+    .govuk-language-switcher-end .govuk-language-switcher__item:not(:first-child):before,
+    .govuk-language-switcher-responsive .govuk-language-switcher__item:not(:first-child):before {
+        top: 0;
+        transform: none
+    }
+}
+
+.govuk-language-switcher__link {
+    font-family: GDS Transport, arial, sans-serif;
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale;
+    text-decoration: underline;
+    text-decoration-thickness: max(1px, .0625rem);
+    text-underline-offset: .1578em
+}
+
+@media print {
+    .govuk-language-switcher__link {
+        font-family: sans-serif
+    }
+}
+
+.govuk-language-switcher__link:hover {
+    text-decoration-thickness: max(3px, .1875rem, .12em);
+    -webkit-text-decoration-skip-ink: none;
+    text-decoration-skip-ink: none;
+    -webkit-text-decoration-skip: none;
+    text-decoration-skip: none
+}
+
+.govuk-language-switcher__link:focus {
+    outline: 3px solid transparent;
+    background-color: var(--govuk-focus-colour, #fd0);
+    box-shadow: 0 -2px var(--govuk-focus-colour, #fd0), 0 4px var(--govuk-focus-text-colour, #0b0c0c);
+    text-decoration: none
+}
+
+@supports not (text-wrap:balance) {
+    .govuk-language-switcher__link:focus {
+        -webkit-box-decoration-break: clone;
+        box-decoration-break: clone
+    }
+}
+
+.govuk-language-switcher__link:not(:hover):not(:active) {
+    text-decoration: none
+}
+
+.govuk-language-switcher__link:link,
+.govuk-language-switcher__link:visited {
+    color: var(--govuk-link-colour, #1a65a6)
+}
+
+.govuk-language-switcher__link:hover {
+    color: var(--govuk-link-hover-colour, #0f385c)
+}
+
+.govuk-language-switcher__link:active {
+    color: var(--govuk-link-active-colour, #0b0c0c)
+}
+
+.govuk-language-switcher__link:focus {
+    color: var(--govuk-focus-text-colour, #0b0c0c)
+}
+
+.govuk-language-switcher-responsive .govuk-language-switcher__toggle {
+    margin-bottom: 0
+}
+
+@media (max-width:40.0525em) {
+    .govuk-language-switcher-responsive .govuk-language-switcher__list {
+        display: block;
+        margin-bottom: 15px
+    }
+
+    .govuk-language-switcher-responsive .govuk-language-switcher__list[hidden] {
+        display: none
+    }
+
+    .govuk-language-switcher-responsive .govuk-language-switcher__item {
+        margin: 10px 0
+    }
+
+    .govuk-language-switcher-responsive .govuk-language-switcher__item:not(:first-child) {
+        margin-left: 0;
+        padding-left: 0
+    }
+
+    .govuk-language-switcher-responsive .govuk-language-switcher__item--icon,
+    .govuk-language-switcher-responsive .govuk-language-switcher__item:not(:first-child):before {
+        display: none
+    }
+}
+
+.govuk-language-switcher__text {
+    font-weight: inherit
+}
+
 .govuk-service-navigation__toggle {
     font-family: GDS Transport, arial, sans-serif;
     -webkit-font-smoothing: antialiased;
@@ -5673,6 +6050,10 @@ screen and (-ms-high-contrast:active) {
     }
 }
 
+.govuk-test-service-navigation {
+    display: block
+}
+
 .govuk-task-list {
     font-family: GDS Transport, arial, sans-serif;
     -webkit-font-smoothing: antialiased;

Action run for 4f519a7

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown

Rendered HTML changes to npm package

diff --git a/packages/govuk-frontend/dist/govuk/components/language-switcher/template-default.html b/packages/govuk-frontend/dist/govuk/components/language-switcher/template-default.html
new file mode 100644
index 000000000..c1e2d6de3
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/language-switcher/template-default.html
@@ -0,0 +1,17 @@
+<nav class="govuk-language-switcher govuk-language-switcher--collapsible" aria-label="Language" data-module="govuk-language-switcher">
+    <button type="button" class="govuk-language-switcher__toggle govuk-js-language-switcher-toggle" aria-controls="language-switcher-navigation" hidden aria-hidden="true">
+      Language
+    </button>
+  <ul class="govuk-language-switcher__list" id="language-switcher-navigation">
+<li class="govuk-language-switcher__item govuk-language-switcher__item--current">
+          <span class="govuk-language-switcher__text" lang="en" aria-current="page">
+            English
+          </span>
+      </li>
+<li class="govuk-language-switcher__item">
+          <a class="govuk-language-switcher__link" href="/cy" hreflang="cy" lang="cy" rel="alternate">
+            Cymraeg
+          </a>
+      </li>
+  </ul>
+</nav>
diff --git a/packages/govuk-frontend/dist/govuk/components/language-switcher/template-with-icon.html b/packages/govuk-frontend/dist/govuk/components/language-switcher/template-with-icon.html
new file mode 100644
index 000000000..1f11657ce
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/language-switcher/template-with-icon.html
@@ -0,0 +1,37 @@
+<nav class="govuk-language-switcher govuk-language-switcher--collapsible" aria-label="Language" data-module="govuk-language-switcher">
+    <button type="button" class="govuk-language-switcher__toggle govuk-js-language-switcher-toggle" aria-controls="language-switcher-navigation" hidden aria-hidden="true">
+          <span class="govuk-language-switcher__icon" aria-hidden="true">
+    <svg class="govuk-language-switcher__icon-svg" xmlns="http://www.w3.org/2000/svg" height="20" width="20" aria-hidden="true" focusable="false" viewBox="0 0 20 20">
+      <circle cx="10" cy="10" r="8" fill="none" stroke="currentcolor" stroke-width="1.5" />
+      <ellipse cx="10" cy="10" rx="3.5" ry="8" fill="none" stroke="currentcolor" stroke-width="1.5" />
+      <line x1="2" y1="10" x2="18" y2="10" stroke="currentcolor" stroke-width="1.5" />
+      <path d="M3.5 6.5h13M3.5 13.5h13" fill="none" stroke="currentcolor" stroke-width="1.5" />
+    </svg>
+  </span>
+
+      Language
+    </button>
+  <ul class="govuk-language-switcher__list" id="language-switcher-navigation">
+      <li class="govuk-language-switcher__item govuk-language-switcher__item--icon" aria-hidden="true">
+          <span class="govuk-language-switcher__icon" aria-hidden="true">
+    <svg class="govuk-language-switcher__icon-svg" xmlns="http://www.w3.org/2000/svg" height="20" width="20" aria-hidden="true" focusable="false" viewBox="0 0 20 20">
+      <circle cx="10" cy="10" r="8" fill="none" stroke="currentcolor" stroke-width="1.5" />
+      <ellipse cx="10" cy="10" rx="3.5" ry="8" fill="none" stroke="currentcolor" stroke-width="1.5" />
+      <line x1="2" y1="10" x2="18" y2="10" stroke="currentcolor" stroke-width="1.5" />
+      <path d="M3.5 6.5h13M3.5 13.5h13" fill="none" stroke="currentcolor" stroke-width="1.5" />
+    </svg>
+  </span>
+
+      </li>
+<li class="govuk-language-switcher__item govuk-language-switcher__item--current">
+          <span class="govuk-language-switcher__text" lang="en" aria-current="page">
+            English
+          </span>
+      </li>
+<li class="govuk-language-switcher__item">
+          <a class="govuk-language-switcher__link" href="/cy" hreflang="cy" lang="cy" rel="alternate">
+            Cymraeg
+          </a>
+      </li>
+  </ul>
+</nav>
diff --git a/packages/govuk-frontend/dist/govuk/components/language-switcher/template-with-mobile-collapse.html b/packages/govuk-frontend/dist/govuk/components/language-switcher/template-with-mobile-collapse.html
new file mode 100644
index 000000000..0efee8333
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/language-switcher/template-with-mobile-collapse.html
@@ -0,0 +1,22 @@
+<nav class="govuk-language-switcher govuk-language-switcher--collapsible" aria-label="Language" data-module="govuk-language-switcher">
+    <button type="button" class="govuk-language-switcher__toggle govuk-js-language-switcher-toggle" aria-controls="language-switcher-navigation" hidden aria-hidden="true">
+      Language
+    </button>
+  <ul class="govuk-language-switcher__list" id="language-switcher-navigation">
+<li class="govuk-language-switcher__item govuk-language-switcher__item--current">
+          <span class="govuk-language-switcher__text" lang="en" aria-current="page">
+            English
+          </span>
+      </li>
+<li class="govuk-language-switcher__item">
+          <a class="govuk-language-switcher__link" href="/cy" hreflang="cy" lang="cy" rel="alternate">
+            Cymraeg
+          </a>
+      </li>
+<li class="govuk-language-switcher__item">
+          <a class="govuk-language-switcher__link" href="/fr" hreflang="fr" lang="fr" rel="alternate">
+            Francais
+          </a>
+      </li>
+  </ul>
+</nav>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-default.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-default.html
index 2d1f277ba..722810de4 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-default.html
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-default.html
@@ -50,8 +50,10 @@ Navigation item 4
 
             </ul>
         </nav>
-    </div>
 
     </div>
 
+    
+  </div>
+
   </div>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-html-navigation-items.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-html-navigation-items.html
index c1a9a0d94..79f5c3a61 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-html-navigation-items.html
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-html-navigation-items.html
@@ -42,8 +42,10 @@ data-module="govuk-service-navigation"
 
             </ul>
         </nav>
-    </div>
 
     </div>
 
+    
+  </div>
+
   </div>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-a-single-navigation-item-and-collapsenavigationonmobile-set-to-true.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-language-switcher-and-icon.html
similarity index 38%
rename from packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-a-single-navigation-item-and-collapsenavigationonmobile-set-to-true.html
rename to packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-language-switcher-and-icon.html
index 3c348378b..d2c2b39ac 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-a-single-navigation-item-and-collapsenavigationonmobile-set-to-true.html
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-language-switcher-and-icon.html
@@ -25,14 +25,50 @@ data-module="govuk-service-navigation"
               <li class="govuk-service-navigation__item">
                   <a class="govuk-service-navigation__link" href="#/1">
                                     
-Log out
+Navigation item 1
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/2">
+                                    
+Navigation item 2
                   </a>
               </li>
 
             </ul>
         </nav>
-    </div>
 
     </div>
 
+            <nav class="govuk-language-switcher govuk-language-switcher-end" aria-label="Language">
+    <ul class="govuk-language-switcher__list">
+        <li class="govuk-language-switcher__item govuk-language-switcher__item--icon" aria-hidden="true">
+            <span class="govuk-language-switcher__icon" aria-hidden="true">
+    <svg class="govuk-language-switcher__icon-svg" xmlns="http://www.w3.org/2000/svg" height="20" width="20" aria-hidden="true" focusable="false" viewBox="0 0 20 20">
+      <circle cx="10" cy="10" r="8" fill="none" stroke="currentcolor" stroke-width="1.5" />
+      <ellipse cx="10" cy="10" rx="3.5" ry="8" fill="none" stroke="currentcolor" stroke-width="1.5" />
+      <line x1="2" y1="10" x2="18" y2="10" stroke="currentcolor" stroke-width="1.5" />
+      <path d="M3.5 6.5h13M3.5 13.5h13" fill="none" stroke="currentcolor" stroke-width="1.5" />
+    </svg>
+  </span>
+
+        </li>
+      <li class="govuk-language-switcher__item govuk-language-switcher__item--current">
+          <span class="govuk-service-navigation__text govuk-language-switcher__text" lang="en" aria-current="page">
+            English
+          </span>
+      </li>
+      <li class="govuk-language-switcher__item">
+          <a class="govuk-service-navigation__link govuk-language-switcher__link" href="/cy" hreflang="cy" lang="cy" rel="alternate">
+            Cymraeg
+          </a>
+      </li>
+    </ul>
+  </nav>
+
+
+  </div>
+
   </section>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-a-single-navigation-item.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-language-switcher-responsive.html
similarity index 20%
rename from packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-a-single-navigation-item.html
rename to packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-language-switcher-responsive.html
index 67244744e..b25cbd053 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-a-single-navigation-item.html
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-language-switcher-responsive.html
@@ -14,6 +14,9 @@ data-module="govuk-service-navigation"
 
       
         <nav aria-label="Menu" class="govuk-service-navigation__wrapper">
+          <button type="button" class="govuk-service-navigation__toggle govuk-js-service-navigation-toggle" aria-controls="navigation" hidden aria-hidden="true">
+            Menu
+          </button>
 
           <ul class="govuk-service-navigation__list" id="navigation" >
 
@@ -22,14 +25,82 @@ data-module="govuk-service-navigation"
               <li class="govuk-service-navigation__item">
                   <a class="govuk-service-navigation__link" href="#/1">
                                     
-Log out
+Navigation item 1
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/2">
+                                    
+Navigation item 2
                   </a>
               </li>
 
             </ul>
         </nav>
-    </div>
 
     </div>
 
+            <nav class="govuk-language-switcher govuk-language-switcher-responsive govuk-language-switcher-responsive" aria-label="Language">
+    <button type="button" class="govuk-service-navigation__toggle govuk-language-switcher__toggle govuk-js-service-navigation-toggle" aria-controls="language-switcher-navigation" hidden aria-hidden="true">
+      Language
+    </button>
+    <ul class="govuk-language-switcher__list" id="language-switcher-navigation">
+        <li class="govuk-language-switcher__item govuk-language-switcher__item--current">
+            <span class="govuk-service-navigation__text govuk-language-switcher__text" lang="en" aria-current="page">
+              English
+            </span>
+        </li>
+        <li class="govuk-language-switcher__item">
+            <a class="govuk-service-navigation__link govuk-language-switcher__link" href="/cy" hreflang="cy" lang="cy" rel="alternate">
+              Cymraeg
+            </a>
+        </li>
+        <li class="govuk-language-switcher__item">
+            <a class="govuk-service-navigation__link govuk-language-switcher__link" href="/fr" hreflang="fr" lang="fr" rel="alternate">
+              Francais
+            </a>
+        </li>
+        <li class="govuk-language-switcher__item">
+            <a class="govuk-service-navigation__link govuk-language-switcher__link" href="/de" hreflang="de" lang="de" rel="alternate">
+              Deutsch
+            </a>
+        </li>
+        <li class="govuk-language-switcher__item">
+            <a class="govuk-service-navigation__link govuk-language-switcher__link" href="/es" hreflang="es" lang="es" rel="alternate">
+              Espanol
+            </a>
+        </li>
+        <li class="govuk-language-switcher__item">
+            <a class="govuk-service-navigation__link govuk-language-switcher__link" href="/it" hreflang="it" lang="it" rel="alternate">
+              Italiano
+            </a>
+        </li>
+        <li class="govuk-language-switcher__item">
+            <a class="govuk-service-navigation__link govuk-language-switcher__link" href="/pt" hreflang="pt" lang="pt" rel="alternate">
+              Portugues
+            </a>
+        </li>
+        <li class="govuk-language-switcher__item">
+            <a class="govuk-service-navigation__link govuk-language-switcher__link" href="/nl" hreflang="nl" lang="nl" rel="alternate">
+              Nederlands
+            </a>
+        </li>
+        <li class="govuk-language-switcher__item">
+            <a class="govuk-service-navigation__link govuk-language-switcher__link" href="/pl" hreflang="pl" lang="pl" rel="alternate">
+              Polski
+            </a>
+        </li>
+        <li class="govuk-language-switcher__item">
+            <a class="govuk-service-navigation__link govuk-language-switcher__link" href="/ga" hreflang="ga" lang="ga" rel="alternate">
+              Gaeilge
+            </a>
+        </li>
+    </ul>
+  </nav>
+
+
+  </div>
+
   </section>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-collapsenavigationonmobile-set-to-false.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-language-switcher-right-aligned.html
similarity index 54%
rename from packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-collapsenavigationonmobile-set-to-false.html
rename to packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-language-switcher-right-aligned.html
index e07e0d62b..2170e8736 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-collapsenavigationonmobile-set-to-false.html
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-language-switcher-right-aligned.html
@@ -14,6 +14,9 @@ data-module="govuk-service-navigation"
 
       
         <nav aria-label="Menu" class="govuk-service-navigation__wrapper">
+          <button type="button" class="govuk-service-navigation__toggle govuk-js-service-navigation-toggle" aria-controls="navigation" hidden aria-hidden="true">
+            Menu
+          </button>
 
           <ul class="govuk-service-navigation__list" id="navigation" >
 
@@ -27,34 +30,34 @@ Navigation item 1
               </li>
 
               
-              <li class="govuk-service-navigation__item govuk-service-navigation__item--active">
-                  <a class="govuk-service-navigation__link" href="#/2" aria-current="true">
-                                    
-                  <strong class="govuk-service-navigation__active-fallback">Navigation item 2</strong>
-
-                  </a>
-              </li>
-
-              
               <li class="govuk-service-navigation__item">
-                  <a class="govuk-service-navigation__link" href="#/3">
+                  <a class="govuk-service-navigation__link" href="#/2">
                                     
-Navigation item 3
-                  </a>
-              </li>
-
-              
-              <li class="govuk-service-navigation__item">
-                  <a class="govuk-service-navigation__link" href="#/4">
-                                    
-Navigation item 4
+Navigation item 2
                   </a>
               </li>
 
             </ul>
         </nav>
-    </div>
+
+          <nav class="govuk-language-switcher govuk-language-switcher-right govuk-language-switcher--right-align" aria-label="Language">
+    <ul class="govuk-language-switcher__list">
+      <li class="govuk-language-switcher__item govuk-language-switcher__item--current">
+          <span class="govuk-service-navigation__text govuk-language-switcher__text" lang="en" aria-current="page">
+            English
+          </span>
+      </li>
+      <li class="govuk-language-switcher__item">
+          <a class="govuk-service-navigation__link govuk-language-switcher__link" href="/cy" hreflang="cy" lang="cy" rel="alternate">
+            Cymraeg
+          </a>
+      </li>
+    </ul>
+  </nav>
 
     </div>
 
+    
+  </div>
+
   </section>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-inverse.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-language-switcher.html
similarity index 64%
rename from packages/govuk-frontend/dist/govuk/components/service-navigation/template-inverse.html
rename to packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-language-switcher.html
index e95f79fcf..ac47c9f47 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-inverse.html
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-language-switcher.html
@@ -1,5 +1,5 @@
 
-  <section aria-label="Service information" class="govuk-service-navigation govuk-service-navigation--inverse"
+  <section aria-label="Service information" class="govuk-service-navigation"
 data-module="govuk-service-navigation"
 >
       <div class="govuk-width-container">
@@ -30,34 +30,34 @@ Navigation item 1
               </li>
 
               
-              <li class="govuk-service-navigation__item govuk-service-navigation__item--active">
-                  <a class="govuk-service-navigation__link" href="#/2" aria-current="true">
-                                    
-                  <strong class="govuk-service-navigation__active-fallback">Navigation item 2</strong>
-
-                  </a>
-              </li>
-
-              
-              <li class="govuk-service-navigation__item">
-                  <a class="govuk-service-navigation__link" href="#/3">
-                                    
-Navigation item 3
-                  </a>
-              </li>
-
-              
               <li class="govuk-service-navigation__item">
-                  <a class="govuk-service-navigation__link" href="#/4">
+                  <a class="govuk-service-navigation__link" href="#/2">
                                     
-Navigation item 4
+Navigation item 2
                   </a>
               </li>
 
             </ul>
         </nav>
-    </div>
 
     </div>
 
+            <nav class="govuk-language-switcher govuk-language-switcher-end" aria-label="Language">
+    <ul class="govuk-language-switcher__list">
+      <li class="govuk-language-switcher__item govuk-language-switcher__item--current">
+          <span class="govuk-service-navigation__text govuk-language-switcher__text" lang="en" aria-current="page">
+            English
+          </span>
+      </li>
+      <li class="govuk-language-switcher__item">
+          <a class="govuk-service-navigation__link govuk-language-switcher__link" href="/cy" hreflang="cy" lang="cy" rel="alternate">
+            Cymraeg
+          </a>
+      </li>
+    </ul>
+  </nav>
+
+
+  </div>
+
   </section>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-large-navigation.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-large-navigation.html
index a7789887d..704f266f4 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-large-navigation.html
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-large-navigation.html
@@ -146,8 +146,10 @@ Working, jobs and pensions
 
             </ul>
         </nav>
-    </div>
 
     </div>
 
+    
+  </div>
+
   </div>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-long-service-name.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-long-service-name.html
index 3fb470853..0a5554f1e 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-long-service-name.html
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-long-service-name.html
@@ -13,8 +13,10 @@ data-module="govuk-service-navigation"
         </span>
 
       
-    </div>
 
     </div>
 
+    
+  </div>
+
   </section>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-navigation-with-a-current-item.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-navigation-with-a-current-item.html
index e31076db0..b58554eea 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-navigation-with-a-current-item.html
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-navigation-with-a-current-item.html
@@ -51,8 +51,10 @@ Navigation item 4
 
             </ul>
         </nav>
-    </div>
 
     </div>
 
+    
+  </div>
+
   </div>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-non-link-navigation-items.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-non-link-navigation-items.html
index 7c9e050e5..bcb5e23a3 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-non-link-navigation-items.html
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-non-link-navigation-items.html
@@ -42,8 +42,10 @@ Navigation item 3
 
             </ul>
         </nav>
-    </div>
 
     </div>
 
+    
+  </div>
+
   </div>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-link.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-link.html
index a722c3f06..64f29bc6a 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-link.html
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-link.html
@@ -13,8 +13,10 @@ data-module="govuk-service-navigation"
         </span>
 
       
-    </div>
 
     </div>
 
+    
+  </div>
+
   </section>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-name-and-navigation.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-name-and-navigation.html
index 7e8c3172c..620eee1f2 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-name-and-navigation.html
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-name-and-navigation.html
@@ -56,8 +56,10 @@ Navigation item 4
 
             </ul>
         </nav>
-    </div>
 
     </div>
 
+    
+  </div>
+
   </section>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-name.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-name.html
index b0bdcf282..03dbf24ad 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-name.html
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-name.html
@@ -11,8 +11,10 @@ data-module="govuk-service-navigation"
         </span>
 
       
-    </div>
 
     </div>
 
+    
+  </div>
+
   </section>
diff --git a/packages/govuk-frontend/dist/govuk/components/test-service-navigation/template-default.html b/packages/govuk-frontend/dist/govuk/components/test-service-navigation/template-default.html
new file mode 100644
index 000000000..2d51115ed
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/test-service-navigation/template-default.html
@@ -0,0 +1,75 @@
+<section aria-label="Service information" class="govuk-test-service-navigation govuk-service-navigation" data-module="govuk-service-navigation">
+  <div class="govuk-width-container">
+    <div class="govuk-service-navigation__container">
+        <span class="govuk-service-navigation__service-name">
+            <a href="#/" class="govuk-service-navigation__link">
+              Apply for a juggling license
+            </a>
+        </span>
+
+        <nav aria-label="Menu" class="govuk-service-navigation__wrapper">
+            <button type="button" class="govuk-service-navigation__toggle govuk-js-service-navigation-toggle" aria-controls="navigation" hidden aria-hidden="true">
+              Menu
+            </button>
+
+          <ul class="govuk-service-navigation__list" id="navigation">
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/1">
+                      Navigation item 1
+                  </a>
+              </li>
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/2">
+                      Navigation item 2
+                  </a>
+              </li>
+          </ul>
+        </nav>
+
+    </div>
+
+      <nav class="govuk-language-switcher govuk-language-switcher-responsive govuk-language-switcher-responsive govuk-language-switcher--collapsible" aria-label="Language" data-module="govuk-language-switcher">
+    <button type="button" class="govuk-language-switcher__toggle govuk-js-language-switcher-toggle" aria-controls="language-switcher-navigation" hidden aria-hidden="true">
+          <span class="govuk-language-switcher__icon" aria-hidden="true">
+    <svg class="govuk-language-switcher__icon-svg" xmlns="http://www.w3.org/2000/svg" height="20" width="20" aria-hidden="true" focusable="false" viewBox="0 0 20 20">
+      <circle cx="10" cy="10" r="8" fill="none" stroke="currentcolor" stroke-width="1.5" />
+      <ellipse cx="10" cy="10" rx="3.5" ry="8" fill="none" stroke="currentcolor" stroke-width="1.5" />
+      <line x1="2" y1="10" x2="18" y2="10" stroke="currentcolor" stroke-width="1.5" />
+      <path d="M3.5 6.5h13M3.5 13.5h13" fill="none" stroke="currentcolor" stroke-width="1.5" />
+    </svg>
+  </span>
+
+      Language
+    </button>
+  <ul class="govuk-language-switcher__list" id="language-switcher-navigation">
+      <li class="govuk-language-switcher__item govuk-language-switcher__item--icon" aria-hidden="true">
+          <span class="govuk-language-switcher__icon" aria-hidden="true">
+    <svg class="govuk-language-switcher__icon-svg" xmlns="http://www.w3.org/2000/svg" height="20" width="20" aria-hidden="true" focusable="false" viewBox="0 0 20 20">
+      <circle cx="10" cy="10" r="8" fill="none" stroke="currentcolor" stroke-width="1.5" />
+      <ellipse cx="10" cy="10" rx="3.5" ry="8" fill="none" stroke="currentcolor" stroke-width="1.5" />
+      <line x1="2" y1="10" x2="18" y2="10" stroke="currentcolor" stroke-width="1.5" />
+      <path d="M3.5 6.5h13M3.5 13.5h13" fill="none" stroke="currentcolor" stroke-width="1.5" />
+    </svg>
+  </span>
+
+      </li>
+<li class="govuk-language-switcher__item govuk-language-switcher__item--current">
+          <span class="govuk-language-switcher__text" lang="en" aria-current="page">
+            English
+          </span>
+      </li>
+<li class="govuk-language-switcher__item">
+          <a class="govuk-language-switcher__link" href="/cy" hreflang="cy" lang="cy" rel="alternate">
+            Cymraeg
+          </a>
+      </li>
+<li class="govuk-language-switcher__item">
+          <a class="govuk-language-switcher__link" href="/fr" hreflang="fr" lang="fr" rel="alternate">
+            Francais
+          </a>
+      </li>
+  </ul>
+</nav>
+
+  </div>
+</section>

Action run for 4f519a7

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown

Other changes to npm package

diff --git a/packages/govuk-frontend/dist/govuk/all.bundle.js b/packages/govuk-frontend/dist/govuk/all.bundle.js
index 1c5cd4a01..f62f56d67 100644
--- a/packages/govuk-frontend/dist/govuk/all.bundle.js
+++ b/packages/govuk-frontend/dist/govuk/all.bundle.js
@@ -1860,6 +1860,114 @@
    * @import { TranslationPluralForms } from '../../i18n.mjs'
    */
 
+  /**
+   * Language Switcher component
+   *
+   * @preserve
+   */
+  class LanguageSwitcher extends Component {
+    /**
+     * @param {Element | null} $root - HTML element to use for language switcher
+     */
+    constructor($root) {
+      super($root);
+      this.controlledMenus = [];
+      this.mql = null;
+      const $menuButton = this.$root.querySelector('.govuk-js-language-switcher-toggle');
+      if (!$menuButton) {
+        return this;
+      }
+      const menuId = $menuButton.getAttribute('aria-controls');
+      if (!menuId) {
+        throw new ElementError({
+          component: LanguageSwitcher,
+          identifier: 'Language switcher button (`<button class="govuk-js-language-switcher-toggle">`) attribute (`aria-controls`)'
+        });
+      }
+      const $menu = document.getElementById(menuId);
+      if (!$menu) {
+        throw new ElementError({
+          component: LanguageSwitcher,
+          element: $menu,
+          identifier: `Language switcher list (\`<ul id="${menuId}">\`)`
+        });
+      }
+      this.controlledMenus = [{
+        $menu,
+        $menuButton,
+        menuIsOpen: false
+      }];
+      this.setupResponsiveChecks();
+      for (const controlledMenu of this.controlledMenus) {
+        controlledMenu.$menuButton.addEventListener('click', () => this.handleMenuButtonClick(controlledMenu));
+      }
+    }
+    setupResponsiveChecks() {
+      const breakpoint = getBreakpoint('tablet');
+      if (!breakpoint.value) {
+        throw new ElementError({
+          component: LanguageSwitcher,
+          identifier: `CSS custom property (\`${breakpoint.property}\`) on pseudo-class \`:root\``
+        });
+      }
+      this.mql = window.matchMedia(`(min-width: ${breakpoint.value})`);
+      if ('addEventListener' in this.mql) {
+        this.mql.addEventListener('change', () => this.checkMode());
+      } else {
+        this.mql.addListener(() => this.checkMode());
+      }
+      this.checkMode();
+    }
+    checkMode() {
+      if (!this.mql) {
+        return;
+      }
+      for (const controlledMenu of this.controlledMenus) {
+        if (this.mql.matches) {
+          controlledMenu.$menu.removeAttribute('hidden');
+          setAttributes$1(controlledMenu.$menuButton, attributesForHidingButton$1);
+        } else {
+          removeAttributes$1(controlledMenu.$menuButton, Object.keys(attributesForHidingButton$1));
+          controlledMenu.$menuButton.setAttribute('aria-expanded', controlledMenu.menuIsOpen.toString());
+          if (controlledMenu.menuIsOpen) {
+            controlledMenu.$menu.removeAttribute('hidden');
+          } else {
+            controlledMenu.$menu.setAttribute('hidden', '');
+          }
+        }
+      }
+    }
+    handleMenuButtonClick(controlledMenu) {
+      controlledMenu.menuIsOpen = !controlledMenu.menuIsOpen;
+      this.checkMode();
+    }
+  }
+  LanguageSwitcher.moduleName = 'govuk-language-switcher';
+  const attributesForHidingButton$1 = {
+    hidden: '',
+    'aria-hidden': 'true'
+  };
+
+  /**
+   * @param {Element} $element - The element to set attributes on
+   * @param {{[attributeName: string]: string}} attributes - The attributes to set
+   */
+  function setAttributes$1($element, attributes) {
+    for (const attributeName in attributes) {
+      $element.setAttribute(attributeName, attributes[attributeName]);
+    }
+  }
+
+  /**
+   * @param {Element} $element - The element to remove attributes from
+   * @param {string[]} attributeNames - The names of attributes to remove
+   */
+  function removeAttributes$1($element, attributeNames) {
+    for (const attributeName of attributeNames) {
+      $element.removeAttribute(attributeName);
+    }
+  }
+
   /**
    * Notification Banner component
    *
@@ -2141,33 +2249,38 @@
      */
     constructor($root) {
       super($root);
-      this.$menuButton = void 0;
-      this.$menu = void 0;
-      this.menuIsOpen = false;
+      this.controlledMenus = [];
       this.mql = null;
-      const $menuButton = this.$root.querySelector('.govuk-js-service-navigation-toggle');
-      if (!$menuButton) {
+      const $menuButtons = this.$root.querySelectorAll('.govuk-js-service-navigation-toggle');
+      if ($menuButtons.length === 0) {
         return this;
       }
-      const menuId = $menuButton.getAttribute('aria-controls');
-      if (!menuId) {
-        throw new ElementError({
-          component: ServiceNavigation,
-          identifier: 'Navigation button (`<button class="govuk-js-service-navigation-toggle">`) attribute (`aria-controls`)'
-        });
-      }
-      const $menu = document.getElementById(menuId);
-      if (!$menu) {
-        throw new ElementError({
-          component: ServiceNavigation,
-          element: $menu,
-          identifier: `Navigation (\`<ul id="${menuId}">\`)`
-        });
-      }
-      this.$menu = $menu;
-      this.$menuButton = $menuButton;
+      this.controlledMenus = Array.from($menuButtons).map($menuButton => {
+        const menuId = $menuButton.getAttribute('aria-controls');
+        if (!menuId) {
+          throw new ElementError({
+            component: ServiceNavigation,
+            identifier: 'Navigation button (`<button class="govuk-js-service-navigation-toggle">`) attribute (`aria-controls`)'
+          });
+        }
+        const $menu = document.getElementById(menuId);
+        if (!$menu) {
+          throw new ElementError({
+            component: ServiceNavigation,
+            element: $menu,
+            identifier: `Navigation (\`<ul id="${menuId}">\`)`
+          });
+        }
+        return {
+          $menu,
+          $menuButton,
+          menuIsOpen: false
+        };
+      });
       this.setupResponsiveChecks();
-      this.$menuButton.addEventListener('click', () => this.handleMenuButtonClick());
+      for (const controlledMenu of this.controlledMenus) {
+        controlledMenu.$menuButton.addEventListener('click', () => this.handleMenuButtonClick(controlledMenu));
+      }
     }
     setupResponsiveChecks() {
       const breakpoint = getBreakpoint('tablet');
@@ -2186,24 +2299,26 @@
       this.checkMode();
     }
     checkMode() {
-      if (!this.mql || !this.$menu || !this.$menuButton) {
+      if (!this.mql) {
         return;
       }
-      if (this.mql.matches) {
-        this.$menu.removeAttribute('hidden');
-        setAttributes(this.$menuButton, attributesForHidingButton);
-      } else {
-        removeAttributes(this.$menuButton, Object.keys(attributesForHidingButton));
-        this.$menuButton.setAttribute('aria-expanded', this.menuIsOpen.toString());
-        if (this.menuIsOpen) {
-          this.$menu.removeAttribute('hidden');
+      for (const controlledMenu of this.controlledMenus) {
+        if (this.mql.matches) {
+          controlledMenu.$menu.removeAttribute('hidden');
+          setAttributes(controlledMenu.$menuButton, attributesForHidingButton);
         } else {
-          this.$menu.setAttribute('hidden', '');
+          removeAttributes(controlledMenu.$menuButton, Object.keys(attributesForHidingButton));
+          controlledMenu.$menuButton.setAttribute('aria-expanded', controlledMenu.menuIsOpen.toString());
+          if (controlledMenu.menuIsOpen) {
+            controlledMenu.$menu.removeAttribute('hidden');
+          } else {
+            controlledMenu.$menu.setAttribute('hidden', '');
+          }
         }
       }
     }
-    handleMenuButtonClick() {
-      this.menuIsOpen = !this.menuIsOpen;
+    handleMenuButtonClick(controlledMenu) {
+      controlledMenu.menuIsOpen = !controlledMenu.menuIsOpen;
       this.checkMode();
     }
   }
@@ -2591,7 +2706,7 @@
       }
       return;
     }
-    const components = [[Accordion, config.accordion], [Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [ExitThisPage, config.exitThisPage], [FileUpload, config.fileUpload], [NotificationBanner, config.notificationBanner], [PasswordInput, config.passwordInput], [Radios], [ServiceNavigation], [SkipLink], [Tabs]];
+    const components = [[Accordion, config.accordion], [Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [ExitThisPage, config.exitThisPage], [FileUpload, config.fileUpload], [LanguageSwitcher], [NotificationBanner, config.notificationBanner], [PasswordInput, config.passwordInput], [Radios], [ServiceNavigation], [SkipLink], [Tabs]];
     components.forEach(([Component, componentConfig]) => {
       createAll(Component, componentConfig, options);
     });
@@ -2724,6 +2839,7 @@
   exports.ErrorSummary = ErrorSummary;
   exports.ExitThisPage = ExitThisPage;
   exports.FileUpload = FileUpload;
+  exports.LanguageSwitcher = LanguageSwitcher;
   exports.NotificationBanner = NotificationBanner;
   exports.PasswordInput = PasswordInput;
   exports.Radios = Radios;
diff --git a/packages/govuk-frontend/dist/govuk/all.bundle.mjs b/packages/govuk-frontend/dist/govuk/all.bundle.mjs
index 1222791b7..453a5ba7a 100644
--- a/packages/govuk-frontend/dist/govuk/all.bundle.mjs
+++ b/packages/govuk-frontend/dist/govuk/all.bundle.mjs
@@ -1854,6 +1854,114 @@ function countFileItems(list) {
  * @import { TranslationPluralForms } from '../../i18n.mjs'
  */
 
+/**
+ * Language Switcher component
+ *
+ * @preserve
+ */
+class LanguageSwitcher extends Component {
+  /**
+   * @param {Element | null} $root - HTML element to use for language switcher
+   */
+  constructor($root) {
+    super($root);
+    this.controlledMenus = [];
+    this.mql = null;
+    const $menuButton = this.$root.querySelector('.govuk-js-language-switcher-toggle');
+    if (!$menuButton) {
+      return this;
+    }
+    const menuId = $menuButton.getAttribute('aria-controls');
+    if (!menuId) {
+      throw new ElementError({
+        component: LanguageSwitcher,
+        identifier: 'Language switcher button (`<button class="govuk-js-language-switcher-toggle">`) attribute (`aria-controls`)'
+      });
+    }
+    const $menu = document.getElementById(menuId);
+    if (!$menu) {
+      throw new ElementError({
+        component: LanguageSwitcher,
+        element: $menu,
+        identifier: `Language switcher list (\`<ul id="${menuId}">\`)`
+      });
+    }
+    this.controlledMenus = [{
+      $menu,
+      $menuButton,
+      menuIsOpen: false
+    }];
+    this.setupResponsiveChecks();
+    for (const controlledMenu of this.controlledMenus) {
+      controlledMenu.$menuButton.addEventListener('click', () => this.handleMenuButtonClick(controlledMenu));
+    }
+  }
+  setupResponsiveChecks() {
+    const breakpoint = getBreakpoint('tablet');
+    if (!breakpoint.value) {
+      throw new ElementError({
+        component: LanguageSwitcher,
+        identifier: `CSS custom property (\`${breakpoint.property}\`) on pseudo-class \`:root\``
+      });
+    }
+    this.mql = window.matchMedia(`(min-width: ${breakpoint.value})`);
+    if ('addEventListener' in this.mql) {
+      this.mql.addEventListener('change', () => this.checkMode());
+    } else {
+      this.mql.addListener(() => this.checkMode());
+    }
+    this.checkMode();
+  }
+  checkMode() {
+    if (!this.mql) {
+      return;
+    }
+    for (const controlledMenu of this.controlledMenus) {
+      if (this.mql.matches) {
+        controlledMenu.$menu.removeAttribute('hidden');
+        setAttributes$1(controlledMenu.$menuButton, attributesForHidingButton$1);
+      } else {
+        removeAttributes$1(controlledMenu.$menuButton, Object.keys(attributesForHidingButton$1));
+        controlledMenu.$menuButton.setAttribute('aria-expanded', controlledMenu.menuIsOpen.toString());
+        if (controlledMenu.menuIsOpen) {
+          controlledMenu.$menu.removeAttribute('hidden');
+        } else {
+          controlledMenu.$menu.setAttribute('hidden', '');
+        }
+      }
+    }
+  }
+  handleMenuButtonClick(controlledMenu) {
+    controlledMenu.menuIsOpen = !controlledMenu.menuIsOpen;
+    this.checkMode();
+  }
+}
+LanguageSwitcher.moduleName = 'govuk-language-switcher';
+const attributesForHidingButton$1 = {
+  hidden: '',
+  'aria-hidden': 'true'
+};
+
+/**
+ * @param {Element} $element - The element to set attributes on
+ * @param {{[attributeName: string]: string}} attributes - The attributes to set
+ */
+function setAttributes$1($element, attributes) {
+  for (const attributeName in attributes) {
+    $element.setAttribute(attributeName, attributes[attributeName]);
+  }
+}
+
+/**
+ * @param {Element} $element - The element to remove attributes from
+ * @param {string[]} attributeNames - The names of attributes to remove
+ */
+function removeAttributes$1($element, attributeNames) {
+  for (const attributeName of attributeNames) {
+    $element.removeAttribute(attributeName);
+  }
+}
+
 /**
  * Notification Banner component
  *
@@ -2135,33 +2243,38 @@ class ServiceNavigation extends Component {
    */
   constructor($root) {
     super($root);
-    this.$menuButton = void 0;
-    this.$menu = void 0;
-    this.menuIsOpen = false;
+    this.controlledMenus = [];
     this.mql = null;
-    const $menuButton = this.$root.querySelector('.govuk-js-service-navigation-toggle');
-    if (!$menuButton) {
+    const $menuButtons = this.$root.querySelectorAll('.govuk-js-service-navigation-toggle');
+    if ($menuButtons.length === 0) {
       return this;
     }
-    const menuId = $menuButton.getAttribute('aria-controls');
-    if (!menuId) {
-      throw new ElementError({
-        component: ServiceNavigation,
-        identifier: 'Navigation button (`<button class="govuk-js-service-navigation-toggle">`) attribute (`aria-controls`)'
-      });
-    }
-    const $menu = document.getElementById(menuId);
-    if (!$menu) {
-      throw new ElementError({
-        component: ServiceNavigation,
-        element: $menu,
-        identifier: `Navigation (\`<ul id="${menuId}">\`)`
-      });
-    }
-    this.$menu = $menu;
-    this.$menuButton = $menuButton;
+    this.controlledMenus = Array.from($menuButtons).map($menuButton => {
+      const menuId = $menuButton.getAttribute('aria-controls');
+      if (!menuId) {
+        throw new ElementError({
+          component: ServiceNavigation,
+          identifier: 'Navigation button (`<button class="govuk-js-service-navigation-toggle">`) attribute (`aria-controls`)'
+        });
+      }
+      const $menu = document.getElementById(menuId);
+      if (!$menu) {
+        throw new ElementError({
+          component: ServiceNavigation,
+          element: $menu,
+          identifier: `Navigation (\`<ul id="${menuId}">\`)`
+        });
+      }
+      return {
+        $menu,
+        $menuButton,
+        menuIsOpen: false
+      };
+    });
     this.setupResponsiveChecks();
-    this.$menuButton.addEventListener('click', () => this.handleMenuButtonClick());
+    for (const controlledMenu of this.controlledMenus) {
+      controlledMenu.$menuButton.addEventListener('click', () => this.handleMenuButtonClick(controlledMenu));
+    }
   }
   setupResponsiveChecks() {
     const breakpoint = getBreakpoint('tablet');
@@ -2180,24 +2293,26 @@ class ServiceNavigation extends Component {
     this.checkMode();
   }
   checkMode() {
-    if (!this.mql || !this.$menu || !this.$menuButton) {
+    if (!this.mql) {
       return;
     }
-    if (this.mql.matches) {
-      this.$menu.removeAttribute('hidden');
-      setAttributes(this.$menuButton, attributesForHidingButton);
-    } else {
-      removeAttributes(this.$menuButton, Object.keys(attributesForHidingButton));
-      this.$menuButton.setAttribute('aria-expanded', this.menuIsOpen.toString());
-      if (this.menuIsOpen) {
-        this.$menu.removeAttribute('hidden');
+    for (const controlledMenu of this.controlledMenus) {
+      if (this.mql.matches) {
+        controlledMenu.$menu.removeAttribute('hidden');
+        setAttributes(controlledMenu.$menuButton, attributesForHidingButton);
       } else {
-        this.$menu.setAttribute('hidden', '');
+        removeAttributes(controlledMenu.$menuButton, Object.keys(attributesForHidingButton));
+        controlledMenu.$menuButton.setAttribute('aria-expanded', controlledMenu.menuIsOpen.toString());
+        if (controlledMenu.menuIsOpen) {
+          controlledMenu.$menu.removeAttribute('hidden');
+        } else {
+          controlledMenu.$menu.setAttribute('hidden', '');
+        }
       }
     }
   }
-  handleMenuButtonClick() {
-    this.menuIsOpen = !this.menuIsOpen;
+  handleMenuButtonClick(controlledMenu) {
+    controlledMenu.menuIsOpen = !controlledMenu.menuIsOpen;
     this.checkMode();
   }
 }
@@ -2585,7 +2700,7 @@ function initAll(scopeOrConfig = {}) {
     }
     return;
   }
-  const components = [[Accordion, config.accordion], [Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [ExitThisPage, config.exitThisPage], [FileUpload, config.fileUpload], [NotificationBanner, config.notificationBanner], [PasswordInput, config.passwordInput], [Radios], [ServiceNavigation], [SkipLink], [Tabs]];
+  const components = [[Accordion, config.accordion], [Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [ExitThisPage, config.exitThisPage], [FileUpload, config.fileUpload], [LanguageSwitcher], [NotificationBanner, config.notificationBanner], [PasswordInput, config.passwordInput], [Radios], [ServiceNavigation], [SkipLink], [Tabs]];
   components.forEach(([Component, componentConfig]) => {
     createAll(Component, componentConfig, options);
   });
@@ -2709,5 +2824,5 @@ function createAll(Component, config, scopeOrOptions) {
  * @property {OnErrorCallback<ComponentClass>} [onError] - callback function if error throw by component on init
  */
 
-export { Accordion, Button, CharacterCount, Checkboxes, Component, ConfigurableComponent, ErrorSummary, ExitThisPage, FileUpload, NotificationBanner, PasswordInput, Radios, ServiceNavigation, SkipLink, Tabs, createAll, initAll, isSupported, version };
+export { Accordion, Button, CharacterCount, Checkboxes, Component, ConfigurableComponent, ErrorSummary, ExitThisPage, FileUpload, LanguageSwitcher, NotificationBanner, PasswordInput, Radios, ServiceNavigation, SkipLink, Tabs, createAll, initAll, isSupported, version };
 //# sourceMappingURL=all.bundle.mjs.map
diff --git a/packages/govuk-frontend/dist/govuk/all.mjs b/packages/govuk-frontend/dist/govuk/all.mjs
index acc574d91..f9ab4c8b8 100644
--- a/packages/govuk-frontend/dist/govuk/all.mjs
+++ b/packages/govuk-frontend/dist/govuk/all.mjs
@@ -6,6 +6,7 @@ export { Checkboxes } from './components/checkboxes/checkboxes.mjs';
 export { ErrorSummary } from './components/error-summary/error-summary.mjs';
 export { ExitThisPage } from './components/exit-this-page/exit-this-page.mjs';
 export { FileUpload } from './components/file-upload/file-upload.mjs';
+export { LanguageSwitcher } from './components/language-switcher/language-switcher.mjs';
 export { NotificationBanner } from './components/notification-banner/notification-banner.mjs';
 export { PasswordInput } from './components/password-input/password-input.mjs';
 export { Radios } from './components/radios/radios.mjs';
diff --git a/packages/govuk-frontend/dist/govuk/components/_index.import.scss b/packages/govuk-frontend/dist/govuk/components/_index.import.scss
index 14d30c106..149257adb 100644
--- a/packages/govuk-frontend/dist/govuk/components/_index.import.scss
+++ b/packages/govuk-frontend/dist/govuk/components/_index.import.scss
@@ -18,6 +18,7 @@
 @import "input";
 @import "inset-text";
 @import "label";
+@import "language-switcher";
 @import "notification-banner";
 @import "pagination";
 @import "panel";
@@ -31,6 +32,7 @@
 @import "table";
 @import "tabs";
 @import "tag";
+@import "test-service-navigation";
 @import "task-list";
 @import "textarea";
 @import "warning-text";
diff --git a/packages/govuk-frontend/dist/govuk/components/_index.scss b/packages/govuk-frontend/dist/govuk/components/_index.scss
index 06170b408..db879448b 100644
--- a/packages/govuk-frontend/dist/govuk/components/_index.scss
+++ b/packages/govuk-frontend/dist/govuk/components/_index.scss
@@ -18,6 +18,7 @@
 @use "input";
 @use "inset-text";
 @use "label";
+@use "language-switcher";
 @use "notification-banner";
 @use "pagination";
 @use "panel";
@@ -31,6 +32,7 @@
 @use "table";
 @use "tabs";
 @use "tag";
+@use "test-service-navigation";
 @use "task-list";
 @use "textarea";
 @use "warning-text";
diff --git a/packages/govuk-frontend/dist/govuk/components/header/_mixin.scss b/packages/govuk-frontend/dist/govuk/components/header/_mixin.scss
index c809f1244..f04376a2e 100644
--- a/packages/govuk-frontend/dist/govuk/components/header/_mixin.scss
+++ b/packages/govuk-frontend/dist/govuk/components/header/_mixin.scss
@@ -17,6 +17,13 @@
     padding: 0 base.govuk-spacing(3);
   }
 
+  .govuk-header__container--with-secondary {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    gap: base.govuk-spacing(3);
+  }
+
   .govuk-header__logo {
     box-sizing: border-box;
 
@@ -25,6 +32,29 @@
     padding-bottom: 14px - $logo-bottom-margin;
   }
 
+  .govuk-header__secondary {
+    margin-left: auto;
+  }
+
+  .govuk-header__secondary .govuk-language-switcher {
+    margin: 0;
+    color: base.govuk-colour("white");
+  }
+
+  .govuk-header__secondary .govuk-language-switcher__link {
+    @include base.govuk-link-style-inverse;
+  }
+
+  .govuk-header__secondary .govuk-language-switcher__toggle {
+    margin: 0;
+    color: inherit;
+  }
+
+  .govuk-header__secondary .govuk-language-switcher-right,
+  .govuk-header__secondary .govuk-language-switcher--right-align {
+    margin: 0;
+  }
+
   .govuk-header__homepage-link {
     // Avoid using the `base.govuk-link-common` mixin because the links in the
     // header get a special treatment, because:
diff --git a/packages/govuk-frontend/dist/govuk/components/header/macro-options.json b/packages/govuk-frontend/dist/govuk/components/header/macro-options.json
index 74bf70a84..640feffc0 100644
--- a/packages/govuk-frontend/dist/govuk/components/header/macro-options.json
+++ b/packages/govuk-frontend/dist/govuk/components/header/macro-options.json
@@ -17,6 +17,12 @@
         "required": false,
         "description": "Classes for the container, useful if you want to make the header fixed width."
     },
+    {
+        "name": "secondaryHtml",
+        "type": "string",
+        "required": false,
+        "description": "HTML rendered inside the header container after the logo block."
+    },
     {
         "name": "classes",
         "type": "string",
diff --git a/packages/govuk-frontend/dist/govuk/components/language-switcher/README.md b/packages/govuk-frontend/dist/govuk/components/language-switcher/README.md
new file mode 100644
index 000000000..d50720d29
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/language-switcher/README.md
@@ -0,0 +1,5 @@
+# Language switcher
+
+Use the language switcher component to let users move between equivalent pages in different languages.
+
+It renders a list of language options and can collapse to a button on small viewports.
diff --git a/packages/govuk-frontend/dist/govuk/components/language-switcher/_index.import.scss b/packages/govuk-frontend/dist/govuk/components/language-switcher/_index.import.scss
new file mode 100644
index 000000000..e06fc7903
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/language-switcher/_index.import.scss
@@ -0,0 +1,2 @@
+@import "language-switcher";
+
diff --git a/packages/govuk-frontend/dist/govuk/components/language-switcher/_index.scss b/packages/govuk-frontend/dist/govuk/components/language-switcher/_index.scss
new file mode 100644
index 000000000..8be2e75f1
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/language-switcher/_index.scss
@@ -0,0 +1,5 @@
+@use "../../custom-properties";
+@use "mixin";
+
+@include mixin.styles;
+
diff --git a/packages/govuk-frontend/dist/govuk/components/language-switcher/_language-switcher.import.scss b/packages/govuk-frontend/dist/govuk/components/language-switcher/_language-switcher.import.scss
new file mode 100644
index 000000000..6b34283aa
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/language-switcher/_language-switcher.import.scss
@@ -0,0 +1,8 @@
+@use "mixin";
+
+@import "../../base";
+
+@include govuk-exports("govuk/component/language-switcher") {
+  @include mixin.styles;
+}
+
diff --git a/packages/govuk-frontend/dist/govuk/components/language-switcher/_mixin.scss b/packages/govuk-frontend/dist/govuk/components/language-switcher/_mixin.scss
new file mode 100644
index 000000000..b3250d888
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/language-switcher/_mixin.scss
@@ -0,0 +1,181 @@
+@use "sass:math";
+
+@use "../../base";
+
+/// @group components/language-switcher
+/// @access private
+@mixin styles {
+  .govuk-language-switcher {
+    @include base.govuk-font($size: 19);
+  }
+
+  .govuk-language-switcher__list {
+    display: flex;
+    flex-wrap: wrap;
+    margin: 0;
+    padding: 0;
+    list-style: none;
+  }
+
+  .govuk-language-switcher__item {
+    margin: 0;
+    padding: 0;
+
+    &:not(:first-child) {
+      position: relative;
+      margin-left: base.govuk-spacing(2);
+      padding-left: base.govuk-spacing(2);
+
+      &::before {
+        content: "";
+        position: absolute;
+        top: 50%;
+        left: 0;
+        height: 1em;
+        transform: translateY(-50%);
+        border-left: 1px solid currentcolor;
+      }
+    }
+
+    @media #{base.govuk-from-breakpoint(tablet)} {
+      display: inline-block;
+      margin-top: 0;
+      margin-bottom: 0;
+      padding: base.govuk-spacing(3) 0;
+      line-height: math.div(29, 19);
+    }
+  }
+
+  .govuk-language-switcher__link {
+    @include base.govuk-link-common;
+    @include base.govuk-link-style-no-underline;
+    @include base.govuk-link-style-no-visited-state;
+  }
+
+  .govuk-language-switcher__text {
+    font-weight: inherit;
+  }
+
+  .govuk-language-switcher__icon {
+    display: inline-flex;
+    align-items: center;
+    filter: grayscale(1);
+    line-height: 1;
+    vertical-align: text-top;
+  }
+
+  .govuk-language-switcher__icon-svg {
+    display: block;
+  }
+
+  .govuk-language-switcher__toggle {
+    @include base.govuk-font($size: 19, $weight: bold);
+    display: inline-flex;
+    align-items: center;
+    margin: base.govuk-spacing(2) 0;
+    padding: 0;
+    border: 0;
+    color: base.govuk-functional-colour(link);
+    background: none;
+    word-break: break-all;
+    cursor: pointer;
+
+    &:focus {
+      @include base.govuk-focused-text;
+    }
+
+    &::after {
+      @include base.govuk-shape-arrow($direction: down, $base: 10px, $display: inline-block);
+      content: "";
+      margin-left: base.govuk-spacing(1);
+    }
+
+    &[aria-expanded="true"]::after {
+      @include base.govuk-shape-arrow($direction: up, $base: 10px, $display: inline-block);
+    }
+
+    &[hidden] {
+      display: none;
+    }
+  }
+
+  .govuk-language-switcher__toggle .govuk-language-switcher__icon {
+    margin-right: base.govuk-spacing(1);
+  }
+
+  .govuk-language-switcher__item--icon + .govuk-language-switcher__item {
+    margin-left: base.govuk-spacing(1);
+    padding-left: 0;
+
+    &::before {
+      display: none;
+    }
+  }
+
+  .govuk-language-switcher--right-align,
+  .govuk-language-switcher-right {
+    margin: base.govuk-spacing(2) 0;
+
+    @media #{base.govuk-from-breakpoint(tablet)} {
+      margin: 0 0 0 auto;
+    }
+  }
+
+  .govuk-language-switcher--post-end,
+  .govuk-language-switcher-end,
+  .govuk-language-switcher-responsive {
+    .govuk-language-switcher__item {
+      @media #{base.govuk-until-breakpoint(tablet)} {
+        padding-bottom: base.govuk-spacing(2);
+      }
+
+      @media #{base.govuk-from-breakpoint(tablet)} {
+        padding-top: 0;
+        line-height: 1;
+      }
+
+      &:not(:first-child)::before {
+        @media #{base.govuk-from-breakpoint(tablet)} {
+          top: 0;
+          transform: none;
+        }
+      }
+    }
+  }
+
+  .govuk-language-switcher--collapsible,
+  .govuk-language-switcher-responsive {
+    .govuk-language-switcher__toggle {
+      margin-bottom: 0;
+    }
+
+    @media #{base.govuk-until-breakpoint(tablet)} {
+      .govuk-language-switcher__list {
+        display: block;
+        margin-bottom: base.govuk-spacing(3);
+
+        &[hidden] {
+          display: none;
+        }
+      }
+
+      .govuk-language-switcher__item {
+        margin: base.govuk-spacing(2) 0;
+
+        &:not(:first-child) {
+          margin-left: 0;
+          padding-left: 0;
+
+          &::before {
+            display: none;
+          }
+        }
+      }
+
+      .govuk-language-switcher__item--icon {
+        display: none;
+      }
+    }
+  }
+}
+
diff --git a/packages/govuk-frontend/dist/govuk/components/language-switcher/fixtures.json b/packages/govuk-frontend/dist/govuk/components/language-switcher/fixtures.json
new file mode 100644
index 000000000..3d97e432c
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/language-switcher/fixtures.json
@@ -0,0 +1,162 @@
+{
+    "component": "language-switcher",
+    "fixtures": [
+        {
+            "name": "default",
+            "options": {
+                "currentLanguage": "en",
+                "items": [
+                    {
+                        "code": "en",
+                        "text": "English",
+                        "href": "/en"
+                    },
+                    {
+                        "code": "cy",
+                        "text": "Cymraeg",
+                        "href": "/cy"
+                    }
+                ]
+            },
+            "hidden": false,
+            "description": "",
+            "pageTemplateOptions": {},
+            "screenshot": true,
+            "html": "<nav class=\"govuk-language-switcher govuk-language-switcher--collapsible\" aria-label=\"Language\" data-module=\"govuk-language-switcher\">\n    <button type=\"button\" class=\"govuk-language-switcher__toggle govuk-js-language-switcher-toggle\" aria-controls=\"language-switcher-navigation\" hidden aria-hidden=\"true\">\n      Language\n    </button>\n  <ul class=\"govuk-language-switcher__list\" id=\"language-switcher-navigation\">\n<li class=\"govuk-language-switcher__item govuk-language-switcher__item--current\">\n          <span class=\"govuk-language-switcher__text\" lang=\"en\" aria-current=\"page\">\n            English\n          </span>\n      </li>\n<li class=\"govuk-language-switcher__item\">\n          <a class=\"govuk-language-switcher__link\" href=\"/cy\" hreflang=\"cy\" lang=\"cy\" rel=\"alternate\">\n            Cymraeg\n          </a>\n      </li>\n  </ul>\n</nav>"
+        },
+        {
+            "name": "with icon",
+            "options": {
+                "currentLanguage": "en",
+                "showIcon": true,
+                "items": [
+                    {
+                        "code": "en",
+                        "text": "English",
+                        "href": "/en"
+                    },
+                    {
+                        "code": "cy",
+                        "text": "Cymraeg",
+                        "href": "/cy"
+                    }
+                ]
+            },
+            "hidden": false,
+            "description": "",
+            "pageTemplateOptions": {},
+            "screenshot": true,
+            "html": "<nav class=\"govuk-language-switcher govuk-language-switcher--collapsible\" aria-label=\"Language\" data-module=\"govuk-language-switcher\">\n    <button type=\"button\" class=\"govuk-language-switcher__toggle govuk-js-language-switcher-toggle\" aria-controls=\"language-switcher-navigation\" hidden aria-hidden=\"true\">\n          <span class=\"govuk-language-switcher__icon\" aria-hidden=\"true\">\n    <svg class=\"govuk-language-switcher__icon-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20\" width=\"20\" aria-hidden=\"true\" focusable=\"false\" viewBox=\"0 0 20 20\">\n      <circle cx=\"10\" cy=\"10\" r=\"8\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n      <ellipse cx=\"10\" cy=\"10\" rx=\"3.5\" ry=\"8\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n      <line x1=\"2\" y1=\"10\" x2=\"18\" y2=\"10\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n      <path d=\"M3.5 6.5h13M3.5 13.5h13\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n    </svg>\n  </span>\n\n      Language\n    </button>\n  <ul class=\"govuk-language-switcher__list\" id=\"language-switcher-navigation\">\n      <li class=\"govuk-language-switcher__item govuk-language-switcher__item--icon\" aria-hidden=\"true\">\n          <span class=\"govuk-language-switcher__icon\" aria-hidden=\"true\">\n    <svg class=\"govuk-language-switcher__icon-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20\" width=\"20\" aria-hidden=\"true\" focusable=\"false\" viewBox=\"0 0 20 20\">\n      <circle cx=\"10\" cy=\"10\" r=\"8\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n      <ellipse cx=\"10\" cy=\"10\" rx=\"3.5\" ry=\"8\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n      <line x1=\"2\" y1=\"10\" x2=\"18\" y2=\"10\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n      <path d=\"M3.5 6.5h13M3.5 13.5h13\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n    </svg>\n  </span>\n\n      </li>\n<li class=\"govuk-language-switcher__item govuk-language-switcher__item--current\">\n          <span class=\"govuk-language-switcher__text\" lang=\"en\" aria-current=\"page\">\n            English\n          </span>\n      </li>\n<li class=\"govuk-language-switcher__item\">\n          <a class=\"govuk-language-switcher__link\" href=\"/cy\" hreflang=\"cy\" lang=\"cy\" rel=\"alternate\">\n            Cymraeg\n          </a>\n      </li>\n  </ul>\n</nav>"
+        },
+        {
+            "name": "with mobile collapse",
+            "options": {
+                "collapseOnMobile": true,
+                "currentLanguage": "en",
+                "items": [
+                    {
+                        "code": "en",
+                        "text": "English",
+                        "href": "/en"
+                    },
+                    {
+                        "code": "cy",
+                        "text": "Cymraeg",
+                        "href": "/cy"
+                    },
+                    {
+                        "code": "fr",
+                        "text": "Francais",
+                        "href": "/fr"
+                    }
+                ]
+            },
+            "hidden": false,
+            "description": "",
+            "pageTemplateOptions": {},
+            "screenshot": {
+                "variants": [
+                    "default",
+                    "no-js"
+                ]
+            },
+            "html": "<nav class=\"govuk-language-switcher govuk-language-switcher--collapsible\" aria-label=\"Language\" data-module=\"govuk-language-switcher\">\n    <button type=\"button\" class=\"govuk-language-switcher__toggle govuk-js-language-switcher-toggle\" aria-controls=\"language-switcher-navigation\" hidden aria-hidden=\"true\">\n      Language\n    </button>\n  <ul class=\"govuk-language-switcher__list\" id=\"language-switcher-navigation\">\n<li class=\"govuk-language-switcher__item govuk-language-switcher__item--current\">\n          <span class=\"govuk-language-switcher__text\" lang=\"en\" aria-current=\"page\">\n            English\n          </span>\n      </li>\n<li class=\"govuk-language-switcher__item\">\n          <a class=\"govuk-language-switcher__link\" href=\"/cy\" hreflang=\"cy\" lang=\"cy\" rel=\"alternate\">\n            Cymraeg\n          </a>\n      </li>\n<li class=\"govuk-language-switcher__item\">\n          <a class=\"govuk-language-switcher__link\" href=\"/fr\" hreflang=\"fr\" lang=\"fr\" rel=\"alternate\">\n            Francais\n          </a>\n      </li>\n  </ul>\n</nav>"
+        },
+        {
+            "name": "classes",
+            "options": {
+                "classes": "app-language-switcher--custom-class",
+                "currentLanguage": "en",
+                "items": [
+                    {
+                        "code": "en",
+                        "text": "English",
+                        "href": "/en"
+                    },
+                    {
+                        "code": "cy",
+                        "text": "Cymraeg",
+                        "href": "/cy"
+                    }
+                ]
+            },
+            "hidden": true,
+            "description": "",
+            "pageTemplateOptions": {},
+            "screenshot": false,
+            "html": "<nav class=\"govuk-language-switcher app-language-switcher--custom-class govuk-language-switcher--collapsible\" aria-label=\"Language\" data-module=\"govuk-language-switcher\">\n    <button type=\"button\" class=\"govuk-language-switcher__toggle govuk-js-language-switcher-toggle\" aria-controls=\"language-switcher-navigation\" hidden aria-hidden=\"true\">\n      Language\n    </button>\n  <ul class=\"govuk-language-switcher__list\" id=\"language-switcher-navigation\">\n<li class=\"govuk-language-switcher__item govuk-language-switcher__item--current\">\n          <span class=\"govuk-language-switcher__text\" lang=\"en\" aria-current=\"page\">\n            English\n          </span>\n      </li>\n<li class=\"govuk-language-switcher__item\">\n          <a class=\"govuk-language-switcher__link\" href=\"/cy\" hreflang=\"cy\" lang=\"cy\" rel=\"alternate\">\n            Cymraeg\n          </a>\n      </li>\n  </ul>\n</nav>"
+        },
+        {
+            "name": "attributes",
+            "options": {
+                "attributes": {
+                    "data-test": "attribute",
+                    "aria-describedby": "language-switcher-help"
+                },
+                "currentLanguage": "en",
+                "items": [
+                    {
+                        "code": "en",
+                        "text": "English",
+                        "href": "/en"
+                    },
+                    {
+                        "code": "cy",
+                        "text": "Cymraeg",
+                        "href": "/cy"
+                    }
+                ]
+            },
+            "hidden": true,
+            "description": "",
+            "pageTemplateOptions": {},
+            "screenshot": false,
+            "html": "<nav class=\"govuk-language-switcher govuk-language-switcher--collapsible\" aria-label=\"Language\" data-module=\"govuk-language-switcher\" data-test=\"attribute\" aria-describedby=\"language-switcher-help\">\n    <button type=\"button\" class=\"govuk-language-switcher__toggle govuk-js-language-switcher-toggle\" aria-controls=\"language-switcher-navigation\" hidden aria-hidden=\"true\">\n      Language\n    </button>\n  <ul class=\"govuk-language-switcher__list\" id=\"language-switcher-navigation\">\n<li class=\"govuk-language-switcher__item govuk-language-switcher__item--current\">\n          <span class=\"govuk-language-switcher__text\" lang=\"en\" aria-current=\"page\">\n            English\n          </span>\n      </li>\n<li class=\"govuk-language-switcher__item\">\n          <a class=\"govuk-language-switcher__link\" href=\"/cy\" hreflang=\"cy\" lang=\"cy\" rel=\"alternate\">\n            Cymraeg\n          </a>\n      </li>\n  </ul>\n</nav>"
+        },
+        {
+            "name": "with explicit current item",
+            "options": {
+                "currentLanguage": "en",
+                "items": [
+                    {
+                        "code": "en",
+                        "text": "English",
+                        "href": "/en",
+                        "current": false
+                    },
+                    {
+                        "code": "cy",
+                        "text": "Cymraeg",
+                        "href": "/cy",
+                        "current": true
+                    }
+                ]
+            },
+            "hidden": true,
+            "description": "",
+            "pageTemplateOptions": {},
+            "screenshot": false,
+            "html": "<nav class=\"govuk-language-switcher govuk-language-switcher--collapsible\" aria-label=\"Language\" data-module=\"govuk-language-switcher\">\n    <button type=\"button\" class=\"govuk-language-switcher__toggle govuk-js-language-switcher-toggle\" aria-controls=\"language-switcher-navigation\" hidden aria-hidden=\"true\">\n      Language\n    </button>\n  <ul class=\"govuk-language-switcher__list\" id=\"language-switcher-navigation\">\n<li class=\"govuk-language-switcher__item govuk-language-switcher__item--current\">\n          <span class=\"govuk-language-switcher__text\" lang=\"en\" aria-current=\"page\">\n            English\n          </span>\n      </li>\n<li class=\"govuk-language-switcher__item govuk-language-switcher__item--current\">\n          <span class=\"govuk-language-switcher__text\" lang=\"cy\" aria-current=\"page\">\n            Cymraeg\n          </span>\n      </li>\n  </ul>\n</nav>"
+        }
+    ]
+}
diff --git a/packages/govuk-frontend/dist/govuk/components/language-switcher/language-switcher.bundle.js b/packages/govuk-frontend/dist/govuk/components/language-switcher/language-switcher.bundle.js
new file mode 100644
index 000000000..6974bc180
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/language-switcher/language-switcher.bundle.js
@@ -0,0 +1,263 @@
+(function (global, factory) {
+  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+  typeof define === 'function' && define.amd ? define(['exports'], factory) :
+  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.GOVUKFrontend = global.GOVUKFrontend || {}));
+})(this, (function (exports) { 'use strict';
+
+  function getBreakpoint(name) {
+    const property = `--govuk-breakpoint-${name}`;
+    const value = window.getComputedStyle(document.documentElement).getPropertyValue(property);
+    return {
+      property,
+      value: value || undefined
+    };
+  }
+  function isInitialised($root, moduleName) {
+    return $root instanceof HTMLElement && $root.hasAttribute(`data-${moduleName}-init`);
+  }
+
+  /**
+   * Checks if GOV.UK Frontend is supported on this page
+   *
+   * Some browsers will load and run our JavaScript but GOV.UK Frontend
+   * won't be supported.
+   *
+   * @param {HTMLElement | null} [$scope] - (internal) `<body>` HTML element checked for browser support
+   * @returns {boolean} Whether GOV.UK Frontend is supported on this page
+   */
+  function isSupported($scope = document.body) {
+    if (!$scope) {
+      return false;
+    }
+    return $scope.classList.contains('govuk-frontend-supported');
+  }
+  function isArray(option) {
+    return Array.isArray(option);
+  }
+  function isObject(option) {
+    return !!option && typeof option === 'object' && !isArray(option);
+  }
+  function formatErrorMessage(Component, message) {
+    return `${Component.moduleName}: ${message}`;
+  }
+  /**
+   * @typedef ComponentWithModuleName
+   * @property {string} moduleName - Name of the component
+   */
+
+  class GOVUKFrontendError extends Error {
+    constructor(...args) {
+      super(...args);
+      this.name = 'GOVUKFrontendError';
+    }
+  }
+  class SupportError extends GOVUKFrontendError {
+    /**
+     * Checks if GOV.UK Frontend is supported on this page
+     *
+     * @param {HTMLElement | null} [$scope] - HTML element `<body>` checked for browser support
+     */
+    constructor($scope = document.body) {
+      const supportMessage = 'noModule' in HTMLScriptElement.prototype ? 'GOV.UK Frontend initialised without `<body class="govuk-frontend-supported">` from template `<script>` snippet' : 'GOV.UK Frontend is not supported in this browser';
+      super($scope ? supportMessage : 'GOV.UK Frontend initialised without `<script type="module">`');
+      this.name = 'SupportError';
+    }
+  }
+  class ElementError extends GOVUKFrontendError {
+    constructor(messageOrOptions) {
+      let message = typeof messageOrOptions === 'string' ? messageOrOptions : '';
+      if (isObject(messageOrOptions)) {
+        const {
+          component,
+          identifier,
+          element,
+          expectedType
+        } = messageOrOptions;
+        message = identifier;
+        message += element ? ` is not of type ${expectedType != null ? expectedType : 'HTMLElement'}` : ' not found';
+        if (component) {
+          message = formatErrorMessage(component, message);
+        }
+      }
+      super(message);
+      this.name = 'ElementError';
+    }
+  }
+  class InitError extends GOVUKFrontendError {
+    constructor(componentOrMessage) {
+      const message = typeof componentOrMessage === 'string' ? componentOrMessage : formatErrorMessage(componentOrMessage, `Root element (\`$root\`) already initialised`);
+      super(message);
+      this.name = 'InitError';
+    }
+  }
+  /**
+   * @import { ComponentWithModuleName } from '../common/index.mjs'
+   */
+
+  class Component {
+    /**
+     * Returns the root element of the component
+     *
+     * @protected
+     * @returns {RootElementType} - the root element of component
+     */
+    get $root() {
+      return this._$root;
+    }
+    constructor($root) {
+      this._$root = void 0;
+      const childConstructor = this.constructor;
+      if (typeof childConstructor.moduleName !== 'string') {
+        throw new InitError(`\`moduleName\` not defined in component`);
+      }
+      if (!($root instanceof childConstructor.elementType)) {
+        throw new ElementError({
+          element: $root,
+          component: childConstructor,
+          identifier: 'Root element (`$root`)',
+          expectedType: childConstructor.elementType.name
+        });
+      } else {
+        this._$root = $root;
+      }
+      childConstructor.checkSupport();
+      this.checkInitialised();
+      const moduleName = childConstructor.moduleName;
+      this.$root.setAttribute(`data-${moduleName}-init`, '');
+    }
+    checkInitialised() {
+      const constructor = this.constructor;
+      const moduleName = constructor.moduleName;
+      if (moduleName && isInitialised(this.$root, moduleName)) {
+        throw new InitError(constructor);
+      }
+    }
+    static checkSupport() {
+      if (!isSupported()) {
+        throw new SupportError();
+      }
+    }
+  }
+
+  /**
+   * @typedef ChildClass
+   * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component
+   */
+
+  /**
+   * @typedef {typeof Component & ChildClass} ChildClassConstructor
+   */
+  Component.elementType = HTMLElement;
+
+  /**
+   * Language Switcher component
+   *
+   * @preserve
+   */
+  class LanguageSwitcher extends Component {
+    /**
+     * @param {Element | null} $root - HTML element to use for language switcher
+     */
+    constructor($root) {
+      super($root);
+      this.controlledMenus = [];
+      this.mql = null;
+      const $menuButton = this.$root.querySelector('.govuk-js-language-switcher-toggle');
+      if (!$menuButton) {
+        return this;
+      }
+      const menuId = $menuButton.getAttribute('aria-controls');
+      if (!menuId) {
+        throw new ElementError({
+          component: LanguageSwitcher,
+          identifier: 'Language switcher button (`<button class="govuk-js-language-switcher-toggle">`) attribute (`aria-controls`)'
+        });
+      }
+      const $menu = document.getElementById(menuId);
+      if (!$menu) {
+        throw new ElementError({
+          component: LanguageSwitcher,
+          element: $menu,
+          identifier: `Language switcher list (\`<ul id="${menuId}">\`)`
+        });
+      }
+      this.controlledMenus = [{
+        $menu,
+        $menuButton,
+        menuIsOpen: false
+      }];
+      this.setupResponsiveChecks();
+      for (const controlledMenu of this.controlledMenus) {
+        controlledMenu.$menuButton.addEventListener('click', () => this.handleMenuButtonClick(controlledMenu));
+      }
+    }
+    setupResponsiveChecks() {
+      const breakpoint = getBreakpoint('tablet');
+      if (!breakpoint.value) {
+        throw new ElementError({
+          component: LanguageSwitcher,
+          identifier: `CSS custom property (\`${breakpoint.property}\`) on pseudo-class \`:root\``
+        });
+      }
+      this.mql = window.matchMedia(`(min-width: ${breakpoint.value})`);
+      if ('addEventListener' in this.mql) {
+        this.mql.addEventListener('change', () => this.checkMode());
+      } else {
+        this.mql.addListener(() => this.checkMode());
+      }
+      this.checkMode();
+    }
+    checkMode() {
+      if (!this.mql) {
+        return;
+      }
+      for (const controlledMenu of this.controlledMenus) {
+        if (this.mql.matches) {
+          controlledMenu.$menu.removeAttribute('hidden');
+          setAttributes(controlledMenu.$menuButton, attributesForHidingButton);
+        } else {
+          removeAttributes(controlledMenu.$menuButton, Object.keys(attributesForHidingButton));
+          controlledMenu.$menuButton.setAttribute('aria-expanded', controlledMenu.menuIsOpen.toString());
+          if (controlledMenu.menuIsOpen) {
+            controlledMenu.$menu.removeAttribute('hidden');
+          } else {
+            controlledMenu.$menu.setAttribute('hidden', '');
+          }
+        }
+      }
+    }
+    handleMenuButtonClick(controlledMenu) {
+      controlledMenu.menuIsOpen = !controlledMenu.menuIsOpen;
+      this.checkMode();
+    }
+  }
+  LanguageSwitcher.moduleName = 'govuk-language-switcher';
+  const attributesForHidingButton = {
+    hidden: '',
+    'aria-hidden': 'true'
+  };
+
+  /**
+   * @param {Element} $element - The element to set attributes on
+   * @param {{[attributeName: string]: string}} attributes - The attributes to set
+   */
+  function setAttributes($element, attributes) {
+    for (const attributeName in attributes) {
+      $element.setAttribute(attributeName, attributes[attributeName]);
+    }
+  }
+
+  /**
+   * @param {Element} $element - The element to remove attributes from
+   * @param {string[]} attributeNames - The names of attributes to remove
+   */
+  function removeAttributes($element, attributeNames) {
+    for (const attributeName of attributeNames) {
+      $element.removeAttribute(attributeName);
+    }
+  }
+
+  exports.LanguageSwitcher = LanguageSwitcher;
+
+}));
+//# sourceMappingURL=language-switcher.bundle.js.map
diff --git a/packages/govuk-frontend/dist/govuk/components/language-switcher/language-switcher.bundle.mjs b/packages/govuk-frontend/dist/govuk/components/language-switcher/language-switcher.bundle.mjs
new file mode 100644
index 000000000..052f95514
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/language-switcher/language-switcher.bundle.mjs
@@ -0,0 +1,255 @@
+function getBreakpoint(name) {
+  const property = `--govuk-breakpoint-${name}`;
+  const value = window.getComputedStyle(document.documentElement).getPropertyValue(property);
+  return {
+    property,
+    value: value || undefined
+  };
+}
+function isInitialised($root, moduleName) {
+  return $root instanceof HTMLElement && $root.hasAttribute(`data-${moduleName}-init`);
+}
+
+/**
+ * Checks if GOV.UK Frontend is supported on this page
+ *
+ * Some browsers will load and run our JavaScript but GOV.UK Frontend
+ * won't be supported.
+ *
+ * @param {HTMLElement | null} [$scope] - (internal) `<body>` HTML element checked for browser support
+ * @returns {boolean} Whether GOV.UK Frontend is supported on this page
+ */
+function isSupported($scope = document.body) {
+  if (!$scope) {
+    return false;
+  }
+  return $scope.classList.contains('govuk-frontend-supported');
+}
+function isArray(option) {
+  return Array.isArray(option);
+}
+function isObject(option) {
+  return !!option && typeof option === 'object' && !isArray(option);
+}
+function formatErrorMessage(Component, message) {
+  return `${Component.moduleName}: ${message}`;
+}
+/**
+ * @typedef ComponentWithModuleName
+ * @property {string} moduleName - Name of the component
+ */
+
+class GOVUKFrontendError extends Error {
+  constructor(...args) {
+    super(...args);
+    this.name = 'GOVUKFrontendError';
+  }
+}
+class SupportError extends GOVUKFrontendError {
+  /**
+   * Checks if GOV.UK Frontend is supported on this page
+   *
+   * @param {HTMLElement | null} [$scope] - HTML element `<body>` checked for browser support
+   */
+  constructor($scope = document.body) {
+    const supportMessage = 'noModule' in HTMLScriptElement.prototype ? 'GOV.UK Frontend initialised without `<body class="govuk-frontend-supported">` from template `<script>` snippet' : 'GOV.UK Frontend is not supported in this browser';
+    super($scope ? supportMessage : 'GOV.UK Frontend initialised without `<script type="module">`');
+    this.name = 'SupportError';
+  }
+}
+class ElementError extends GOVUKFrontendError {
+  constructor(messageOrOptions) {
+    let message = typeof messageOrOptions === 'string' ? messageOrOptions : '';
+    if (isObject(messageOrOptions)) {
+      const {
+        component,
+        identifier,
+        element,
+        expectedType
+      } = messageOrOptions;
+      message = identifier;
+      message += element ? ` is not of type ${expectedType != null ? expectedType : 'HTMLElement'}` : ' not found';
+      if (component) {
+        message = formatErrorMessage(component, message);
+      }
+    }
+    super(message);
+    this.name = 'ElementError';
+  }
+}
+class InitError extends GOVUKFrontendError {
+  constructor(componentOrMessage) {
+    const message = typeof componentOrMessage === 'string' ? componentOrMessage : formatErrorMessage(componentOrMessage, `Root element (\`$root\`) already initialised`);
+    super(message);
+    this.name = 'InitError';
+  }
+}
+/**
+ * @import { ComponentWithModuleName } from '../common/index.mjs'
+ */
+
+class Component {
+  /**
+   * Returns the root element of the component
+   *
+   * @protected
+   * @returns {RootElementType} - the root element of component
+   */
+  get $root() {
+    return this._$root;
+  }
+  constructor($root) {
+    this._$root = void 0;
+    const childConstructor = this.constructor;
+    if (typeof childConstructor.moduleName !== 'string') {
+      throw new InitError(`\`moduleName\` not defined in component`);
+    }
+    if (!($root instanceof childConstructor.elementType)) {
+      throw new ElementError({
+        element: $root,
+        component: childConstructor,
+        identifier: 'Root element (`$root`)',
+        expectedType: childConstructor.elementType.name
+      });
+    } else {
+      this._$root = $root;
+    }
+    childConstructor.checkSupport();
+    this.checkInitialised();
+    const moduleName = childConstructor.moduleName;
+    this.$root.setAttribute(`data-${moduleName}-init`, '');
+  }
+  checkInitialised() {
+    const constructor = this.constructor;
+    const moduleName = constructor.moduleName;
+    if (moduleName && isInitialised(this.$root, moduleName)) {
+      throw new InitError(constructor);
+    }
+  }
+  static checkSupport() {
+    if (!isSupported()) {
+      throw new SupportError();
+    }
+  }
+}
+
+/**
+ * @typedef ChildClass
+ * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component
+ */
+
+/**
+ * @typedef {typeof Component & ChildClass} ChildClassConstructor
+ */
+Component.elementType = HTMLElement;
+
+/**
+ * Language Switcher component
+ *
+ * @preserve
+ */
+class LanguageSwitcher extends Component {
+  /**
+   * @param {Element | null} $root - HTML element to use for language switcher
+   */
+  constructor($root) {
+    super($root);
+    this.controlledMenus = [];
+    this.mql = null;
+    const $menuButton = this.$root.querySelector('.govuk-js-language-switcher-toggle');
+    if (!$menuButton) {
+      return this;
+    }
+    const menuId = $menuButton.getAttribute('aria-controls');
+    if (!menuId) {
+      throw new ElementError({
+        component: LanguageSwitcher,
+        identifier: 'Language switcher button (`<button class="govuk-js-language-switcher-toggle">`) attribute (`aria-controls`)'
+      });
+    }
+    const $menu = document.getElementById(menuId);
+    if (!$menu) {
+      throw new ElementError({
+        component: LanguageSwitcher,
+        element: $menu,
+        identifier: `Language switcher list (\`<ul id="${menuId}">\`)`
+      });
+    }
+    this.controlledMenus = [{
+      $menu,
+      $menuButton,
+      menuIsOpen: false
+    }];
+    this.setupResponsiveChecks();
+    for (const controlledMenu of this.controlledMenus) {
+      controlledMenu.$menuButton.addEventListener('click', () => this.handleMenuButtonClick(controlledMenu));
+    }
+  }
+  setupResponsiveChecks() {
+    const breakpoint = getBreakpoint('tablet');
+    if (!breakpoint.value) {
+      throw new ElementError({
+        component: LanguageSwitcher,
+        identifier: `CSS custom property (\`${breakpoint.property}\`) on pseudo-class \`:root\``
+      });
+    }
+    this.mql = window.matchMedia(`(min-width: ${breakpoint.value})`);
+    if ('addEventListener' in this.mql) {
+      this.mql.addEventListener('change', () => this.checkMode());
+    } else {
+      this.mql.addListener(() => this.checkMode());
+    }
+    this.checkMode();
+  }
+  checkMode() {
+    if (!this.mql) {
+      return;
+    }
+    for (const controlledMenu of this.controlledMenus) {
+      if (this.mql.matches) {
+        controlledMenu.$menu.removeAttribute('hidden');
+        setAttributes(controlledMenu.$menuButton, attributesForHidingButton);
+      } else {
+        removeAttributes(controlledMenu.$menuButton, Object.keys(attributesForHidingButton));
+        controlledMenu.$menuButton.setAttribute('aria-expanded', controlledMenu.menuIsOpen.toString());
+        if (controlledMenu.menuIsOpen) {
+          controlledMenu.$menu.removeAttribute('hidden');
+        } else {
+          controlledMenu.$menu.setAttribute('hidden', '');
+        }
+      }
+    }
+  }
+  handleMenuButtonClick(controlledMenu) {
+    controlledMenu.menuIsOpen = !controlledMenu.menuIsOpen;
+    this.checkMode();
+  }
+}
+LanguageSwitcher.moduleName = 'govuk-language-switcher';
+const attributesForHidingButton = {
+  hidden: '',
+  'aria-hidden': 'true'
+};
+
+/**
+ * @param {Element} $element - The element to set attributes on
+ * @param {{[attributeName: string]: string}} attributes - The attributes to set
+ */
+function setAttributes($element, attributes) {
+  for (const attributeName in attributes) {
+    $element.setAttribute(attributeName, attributes[attributeName]);
+  }
+}
+
+/**
+ * @param {Element} $element - The element to remove attributes from
+ * @param {string[]} attributeNames - The names of attributes to remove
+ */
+function removeAttributes($element, attributeNames) {
+  for (const attributeName of attributeNames) {
+    $element.removeAttribute(attributeName);
+  }
+}
+
+export { LanguageSwitcher };
+//# sourceMappingURL=language-switcher.bundle.mjs.map
diff --git a/packages/govuk-frontend/dist/govuk/components/language-switcher/language-switcher.mjs b/packages/govuk-frontend/dist/govuk/components/language-switcher/language-switcher.mjs
new file mode 100644
index 000000000..139ea3e7e
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/language-switcher/language-switcher.mjs
@@ -0,0 +1,114 @@
+import { getBreakpoint } from '../../common/index.mjs';
+import { Component } from '../../component.mjs';
+import { ElementError } from '../../errors/index.mjs';
+
+/**
+ * Language Switcher component
+ *
+ * @preserve
+ */
+class LanguageSwitcher extends Component {
+  /**
+   * @param {Element | null} $root - HTML element to use for language switcher
+   */
+  constructor($root) {
+    super($root);
+    this.controlledMenus = [];
+    this.mql = null;
+    const $menuButton = this.$root.querySelector('.govuk-js-language-switcher-toggle');
+    if (!$menuButton) {
+      return this;
+    }
+    const menuId = $menuButton.getAttribute('aria-controls');
+    if (!menuId) {
+      throw new ElementError({
+        component: LanguageSwitcher,
+        identifier: 'Language switcher button (`<button class="govuk-js-language-switcher-toggle">`) attribute (`aria-controls`)'
+      });
+    }
+    const $menu = document.getElementById(menuId);
+    if (!$menu) {
+      throw new ElementError({
+        component: LanguageSwitcher,
+        element: $menu,
+        identifier: `Language switcher list (\`<ul id="${menuId}">\`)`
+      });
+    }
+    this.controlledMenus = [{
+      $menu,
+      $menuButton,
+      menuIsOpen: false
+    }];
+    this.setupResponsiveChecks();
+    for (const controlledMenu of this.controlledMenus) {
+      controlledMenu.$menuButton.addEventListener('click', () => this.handleMenuButtonClick(controlledMenu));
+    }
+  }
+  setupResponsiveChecks() {
+    const breakpoint = getBreakpoint('tablet');
+    if (!breakpoint.value) {
+      throw new ElementError({
+        component: LanguageSwitcher,
+        identifier: `CSS custom property (\`${breakpoint.property}\`) on pseudo-class \`:root\``
+      });
+    }
+    this.mql = window.matchMedia(`(min-width: ${breakpoint.value})`);
+    if ('addEventListener' in this.mql) {
+      this.mql.addEventListener('change', () => this.checkMode());
+    } else {
+      this.mql.addListener(() => this.checkMode());
+    }
+    this.checkMode();
+  }
+  checkMode() {
+    if (!this.mql) {
+      return;
+    }
+    for (const controlledMenu of this.controlledMenus) {
+      if (this.mql.matches) {
+        controlledMenu.$menu.removeAttribute('hidden');
+        setAttributes(controlledMenu.$menuButton, attributesForHidingButton);
+      } else {
+        removeAttributes(controlledMenu.$menuButton, Object.keys(attributesForHidingButton));
+        controlledMenu.$menuButton.setAttribute('aria-expanded', controlledMenu.menuIsOpen.toString());
+        if (controlledMenu.menuIsOpen) {
+          controlledMenu.$menu.removeAttribute('hidden');
+        } else {
+          controlledMenu.$menu.setAttribute('hidden', '');
+        }
+      }
+    }
+  }
+  handleMenuButtonClick(controlledMenu) {
+    controlledMenu.menuIsOpen = !controlledMenu.menuIsOpen;
+    this.checkMode();
+  }
+}
+LanguageSwitcher.moduleName = 'govuk-language-switcher';
+const attributesForHidingButton = {
+  hidden: '',
+  'aria-hidden': 'true'
+};
+
+/**
+ * @param {Element} $element - The element to set attributes on
+ * @param {{[attributeName: string]: string}} attributes - The attributes to set
+ */
+function setAttributes($element, attributes) {
+  for (const attributeName in attributes) {
+    $element.setAttribute(attributeName, attributes[attributeName]);
+  }
+}
+
+/**
+ * @param {Element} $element - The element to remove attributes from
+ * @param {string[]} attributeNames - The names of attributes to remove
+ */
+function removeAttributes($element, attributeNames) {
+  for (const attributeName of attributeNames) {
+    $element.removeAttribute(attributeName);
+  }
+}
+
+export { LanguageSwitcher };
+//# sourceMappingURL=language-switcher.mjs.map
diff --git a/packages/govuk-frontend/dist/govuk/components/language-switcher/macro-options.json b/packages/govuk-frontend/dist/govuk/components/language-switcher/macro-options.json
new file mode 100644
index 000000000..54f762cf4
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/language-switcher/macro-options.json
@@ -0,0 +1,88 @@
+[
+    {
+        "name": "items",
+        "type": "array",
+        "required": true,
+        "description": "Language options shown in the switcher.",
+        "params": [
+            {
+                "name": "code",
+                "type": "string",
+                "required": true,
+                "description": "Language code used for `lang` and `hreflang`."
+            },
+            {
+                "name": "text",
+                "type": "string",
+                "required": true,
+                "description": "Language name shown to users."
+            },
+            {
+                "name": "href",
+                "type": "string",
+                "required": false,
+                "description": "URL for the language link. Ignored when the item is current."
+            },
+            {
+                "name": "current",
+                "type": "boolean",
+                "required": false,
+                "description": "Marks this language as current. Takes precedence over `currentLanguage`."
+            }
+        ]
+    },
+    {
+        "name": "currentLanguage",
+        "type": "string",
+        "required": false,
+        "description": "Language code for the current language. Defaults to matching no item."
+    },
+    {
+        "name": "collapseOnMobile",
+        "type": "boolean",
+        "required": false,
+        "description": "Whether to collapse the language list behind a button on mobile viewports. Defaults to `true`."
+    },
+    {
+        "name": "menuButtonText",
+        "type": "string",
+        "required": false,
+        "description": "Text used for the collapse toggle button. Defaults to `Language`."
+    },
+    {
+        "name": "menuButtonLabel",
+        "type": "string",
+        "required": false,
+        "description": "Accessible label for the collapse toggle button. Defaults to `menuButtonText`."
+    },
+    {
+        "name": "ariaLabel",
+        "type": "string",
+        "required": false,
+        "description": "Label for the language navigation landmark. Defaults to `Language`."
+    },
+    {
+        "name": "navigationId",
+        "type": "string",
+        "required": false,
+        "description": "ID used to associate the collapse toggle with the list. Defaults to `language-switcher-navigation`."
+    },
+    {
+        "name": "showIcon",
+        "type": "boolean",
+        "required": false,
+        "description": "If `true`, shows a globe icon before the first language option."
+    },
+    {
+        "name": "classes",
+        "type": "string",
+        "required": false,
+        "description": "Classes to add to the component container."
+    },
+    {
+        "name": "attributes",
+        "type": "object",
+        "required": false,
+        "description": "HTML attributes (for example, data attributes) to add to the component container."
+    }
+]
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/_mixin.scss b/packages/govuk-frontend/dist/govuk/components/service-navigation/_mixin.scss
index 96d26fc6c..2ab2b4479 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/_mixin.scss
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/_mixin.scss
@@ -116,6 +116,146 @@
     flex-grow: 1;
   }
 
+  .govuk-language-switcher {
+    @include base.govuk-font($size: 19);
+  }
+
+  .govuk-language-switcher-right,
+  .govuk-language-switcher--right-align {
+    margin: base.govuk-spacing(2) 0;
+
+    @media #{base.govuk-from-breakpoint(tablet)} {
+      margin: 0 0 0 auto;
+    }
+  }
+
+  .govuk-language-switcher__list {
+    display: flex;
+    flex-wrap: wrap;
+    margin: 0;
+    padding: 0;
+    list-style: none;
+  }
+
+  .govuk-language-switcher__item {
+    margin: 0;
+    padding: 0;
+
+    &:not(:first-child) {
+      position: relative;
+      margin-left: base.govuk-spacing(2);
+      padding-left: base.govuk-spacing(2);
+
+      &::before {
+        content: "";
+        position: absolute;
+        top: 50%;
+        left: 0;
+        height: 1em;
+        transform: translateY(-50%);
+        border-left: 1px solid currentcolor;
+      }
+    }
+
+    @media #{base.govuk-from-breakpoint(tablet)} {
+      display: inline-block;
+      margin-top: 0;
+      margin-bottom: 0;
+      padding: base.govuk-spacing(3) 0;
+      line-height: math.div(29, 19);
+    }
+  }
+
+  .govuk-language-switcher__icon {
+    display: inline-flex;
+    align-items: center;
+    filter: grayscale(1);
+    line-height: 1;
+    vertical-align: text-top;
+  }
+
+  .govuk-language-switcher__icon-svg {
+    display: block;
+  }
+
+  .govuk-language-switcher__toggle .govuk-language-switcher__icon {
+    margin-right: base.govuk-spacing(1);
+  }
+
+  .govuk-language-switcher__item--icon + .govuk-language-switcher__item {
+    margin-left: base.govuk-spacing(1);
+    padding-left: 0;
+
+    &::before {
+      display: none;
+    }
+  }
+
+  .govuk-language-switcher-end,
+  .govuk-language-switcher-responsive {
+    .govuk-language-switcher__item {
+      @media #{base.govuk-until-breakpoint(tablet)} {
+        padding-bottom: base.govuk-spacing(2);
+      }
+
+      @media #{base.govuk-from-breakpoint(tablet)} {
+        padding-top: 0;
+        line-height: 1;
+      }
+
+      &:not(:first-child)::before {
+        @media #{base.govuk-from-breakpoint(tablet)} {
+          top: 0;
+          transform: none;
+        }
+      }
+    }
+  }
+
+  .govuk-language-switcher__link {
+    @include base.govuk-link-common;
+    @include base.govuk-link-style-no-underline;
+    @include base.govuk-link-style-no-visited-state;
+  }
+
+  .govuk-language-switcher-responsive {
+    .govuk-language-switcher__toggle {
+      margin-bottom: 0;
+    }
+
+    @media #{base.govuk-until-breakpoint(tablet)} {
+      .govuk-language-switcher__list {
+        display: block;
+        margin-bottom: base.govuk-spacing(3);
+
+        &[hidden] {
+          display: none;
+        }
+      }
+
+      .govuk-language-switcher__item {
+        margin: base.govuk-spacing(2) 0;
+
+        &:not(:first-child) {
+          margin-left: 0;
+          padding-left: 0;
+
+          &::before {
+            display: none;
+          }
+        }
+      }
+
+      .govuk-language-switcher__item--icon {
+        display: none;
+      }
+    }
+  }
+
+  .govuk-language-switcher__text {
+    font-weight: inherit;
+  }
+
   //
   // Navigation list specific code
   //
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/fixtures.json b/packages/govuk-frontend/dist/govuk/components/service-navigation/fixtures.json
index 9161446e0..7a61fba4e 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/fixtures.json
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/fixtures.json
@@ -32,7 +32,7 @@
                     "no-js"
                 ]
             },
-            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n                                    \nNavigation item 3\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/4\">\n                                    \nNavigation item 4\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n                                    \nNavigation item 3\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/4\">\n                                    \nNavigation item 4\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n    \n  </div>\n\n  </div>"
         },
         {
             "name": "with navigation with a current item",
@@ -61,7 +61,7 @@
             "description": "The current item indicates that the user is present on that exact page. It looks the same as an active item, but marks this item as the one the user is currently viewing in ARIA.",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item govuk-service-navigation__item--active\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\" aria-current=\"page\">\n                                    \n                  <strong class=\"govuk-service-navigation__active-fallback\">Navigation item 2</strong>\n\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n                                    \nNavigation item 3\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/4\">\n                                    \nNavigation item 4\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item govuk-service-navigation__item--active\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\" aria-current=\"page\">\n                                    \n                  <strong class=\"govuk-service-navigation__active-fallback\">Navigation item 2</strong>\n\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n                                    \nNavigation item 3\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/4\">\n                                    \nNavigation item 4\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n    \n  </div>\n\n  </div>"
         },
         {
             "name": "with large navigation",
@@ -137,7 +137,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/benefits\">\n                                    \nBenefits\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/births-deaths-marriages\">\n                                    \nBirths, deaths, marriages and care\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/business\">\n                                    \nBusiness and self-employed\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/childcare-parenting\">\n                                    \nChildcare and parenting\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/citizenship\">\n                                    \nCitizenship and living in the UK\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/justice\">\n                                    \nCrime, justice and the law\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/disabilities\">\n                                    \nDisabled people\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/driving\">\n                                    \nDriving and transport\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/education\">\n                                    \nEducation and learning\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/employing-people\">\n                                    \nEmploying people\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/environment-countryside\">\n                                    \nEnvironment and countryside\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/housing-local-services\">\n                                    \nHousing and local services\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/tax\">\n                                    \nMoney and tax\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/abroad\">\n                                    \nPassports, travel and living abroad\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/visas-immigration\">\n                                    \nVisas and immigration\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/working\">\n                                    \nWorking, jobs and pensions\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/benefits\">\n                                    \nBenefits\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/births-deaths-marriages\">\n                                    \nBirths, deaths, marriages and care\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/business\">\n                                    \nBusiness and self-employed\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/childcare-parenting\">\n                                    \nChildcare and parenting\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/citizenship\">\n                                    \nCitizenship and living in the UK\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/justice\">\n                                    \nCrime, justice and the law\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/disabilities\">\n                                    \nDisabled people\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/driving\">\n                                    \nDriving and transport\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/education\">\n                                    \nEducation and learning\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/employing-people\">\n                                    \nEmploying people\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/environment-countryside\">\n                                    \nEnvironment and countryside\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/housing-local-services\">\n                                    \nHousing and local services\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/tax\">\n                                    \nMoney and tax\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/abroad\">\n                                    \nPassports, travel and living abroad\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/visas-immigration\">\n                                    \nVisas and immigration\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/working\">\n                                    \nWorking, jobs and pensions\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n    \n  </div>\n\n  </div>"
         },
         {
             "name": "with HTML navigation items",
@@ -161,7 +161,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \n<em>Navigation item 1</em>\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \n<em>Navigation item 2</em>\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n                                    \n<em>Navigation item 3</em>\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \n<em>Navigation item 1</em>\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \n<em>Navigation item 2</em>\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n                                    \n<em>Navigation item 3</em>\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n    \n  </div>\n\n  </div>"
         },
         {
             "name": "with non-link navigation items",
@@ -182,7 +182,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <span class=\"govuk-service-navigation__text\">\n                                    \nNavigation item 1\n                  </span>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <span class=\"govuk-service-navigation__text\">\n                                    \n<em>Navigation item 2</em>\n                  </span>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <span class=\"govuk-service-navigation__text\">\n                                    \nNavigation item 3\n                  </span>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <span class=\"govuk-service-navigation__text\">\n                                    \nNavigation item 1\n                  </span>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <span class=\"govuk-service-navigation__text\">\n                                    \n<em>Navigation item 2</em>\n                  </span>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <span class=\"govuk-service-navigation__text\">\n                                    \nNavigation item 3\n                  </span>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n    \n  </div>\n\n  </div>"
         },
         {
             "name": "with service name",
@@ -193,7 +193,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <span class=\"govuk-service-navigation__text\">Service name</span>\n        </span>\n\n      \n    </div>\n\n    </div>\n\n  </section>"
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <span class=\"govuk-service-navigation__text\">Service name</span>\n        </span>\n\n      \n\n    </div>\n\n    \n  </div>\n\n  </section>"
         },
         {
             "name": "with service link",
@@ -205,7 +205,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Service name\n            </a>\n        </span>\n\n      \n    </div>\n\n    </div>\n\n  </section>"
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Service name\n            </a>\n        </span>\n\n      \n\n    </div>\n\n    \n  </div>\n\n  </section>"
         },
         {
             "name": "with long service name",
@@ -217,7 +217,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Apply to receive a rare holofoil Charizard Pokémon card from the King\n            </a>\n        </span>\n\n      \n    </div>\n\n    </div>\n\n  </section>"
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Apply to receive a rare holofoil Charizard Pokémon card from the King\n            </a>\n        </span>\n\n      \n\n    </div>\n\n    \n  </div>\n\n  </section>"
         },
         {
             "name": "with service name and navigation",
@@ -253,7 +253,168 @@
                     "no-js"
                 ]
             },
-            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Apply for a juggling license\n            </a>\n        </span>\n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item govuk-service-navigation__item--active\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\" aria-current=\"true\">\n                                    \n                  <strong class=\"govuk-service-navigation__active-fallback\">Navigation item 2</strong>\n\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n                                    \nNavigation item 3\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/4\">\n                                    \nNavigation item 4\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </section>"
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Apply for a juggling license\n            </a>\n        </span>\n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item govuk-service-navigation__item--active\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\" aria-current=\"true\">\n                                    \n                  <strong class=\"govuk-service-navigation__active-fallback\">Navigation item 2</strong>\n\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n                                    \nNavigation item 3\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/4\">\n                                    \nNavigation item 4\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n    \n  </div>\n\n  </section>"
+        },
+        {
+            "name": "with language switcher",
+            "options": {
+                "serviceName": "Apply for a juggling license",
+                "serviceUrl": "#/",
+                "navigation": [
+                    {
+                        "href": "#/1",
+                        "text": "Navigation item 1"
+                    },
+                    {
+                        "href": "#/2",
+                        "text": "Navigation item 2"
+                    }
+                ],
+                "languageSwitch": {
+                    "currentLanguage": "en",
+                    "englishHref": "/en",
+                    "welshHref": "/cy"
+                }
+            },
+            "hidden": false,
+            "description": "",
+            "pageTemplateOptions": {},
+            "screenshot": false,
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Apply for a juggling license\n            </a>\n        </span>\n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n            <nav class=\"govuk-language-switcher govuk-language-switcher-end\" aria-label=\"Language\">\n    <ul class=\"govuk-language-switcher__list\">\n      <li class=\"govuk-language-switcher__item govuk-language-switcher__item--current\">\n          <span class=\"govuk-service-navigation__text govuk-language-switcher__text\" lang=\"en\" aria-current=\"page\">\n            English\n          </span>\n      </li>\n      <li class=\"govuk-language-switcher__item\">\n          <a class=\"govuk-service-navigation__link govuk-language-switcher__link\" href=\"/cy\" hreflang=\"cy\" lang=\"cy\" rel=\"alternate\">\n            Cymraeg\n          </a>\n      </li>\n    </ul>\n  </nav>\n\n\n  </div>\n\n  </section>"
+        },
+        {
+            "name": "with language switcher and icon",
+            "options": {
+                "serviceName": "Apply for a juggling license",
+                "serviceUrl": "#/",
+                "navigation": [
+                    {
+                        "href": "#/1",
+                        "text": "Navigation item 1"
+                    },
+                    {
+                        "href": "#/2",
+                        "text": "Navigation item 2"
+                    }
+                ],
+                "languageSwitch": {
+                    "currentLanguage": "en",
+                    "englishHref": "/en",
+                    "welshHref": "/cy",
+                    "showIcon": true
+                }
+            },
+            "hidden": false,
+            "description": "",
+            "pageTemplateOptions": {},
+            "screenshot": false,
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Apply for a juggling license\n            </a>\n        </span>\n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n            <nav class=\"govuk-language-switcher govuk-language-switcher-end\" aria-label=\"Language\">\n    <ul class=\"govuk-language-switcher__list\">\n        <li class=\"govuk-language-switcher__item govuk-language-switcher__item--icon\" aria-hidden=\"true\">\n            <span class=\"govuk-language-switcher__icon\" aria-hidden=\"true\">\n    <svg class=\"govuk-language-switcher__icon-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20\" width=\"20\" aria-hidden=\"true\" focusable=\"false\" viewBox=\"0 0 20 20\">\n      <circle cx=\"10\" cy=\"10\" r=\"8\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n      <ellipse cx=\"10\" cy=\"10\" rx=\"3.5\" ry=\"8\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n      <line x1=\"2\" y1=\"10\" x2=\"18\" y2=\"10\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n      <path d=\"M3.5 6.5h13M3.5 13.5h13\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n    </svg>\n  </span>\n\n        </li>\n      <li class=\"govuk-language-switcher__item govuk-language-switcher__item--current\">\n          <span class=\"govuk-service-navigation__text govuk-language-switcher__text\" lang=\"en\" aria-current=\"page\">\n            English\n          </span>\n      </li>\n      <li class=\"govuk-language-switcher__item\">\n          <a class=\"govuk-service-navigation__link govuk-language-switcher__link\" href=\"/cy\" hreflang=\"cy\" lang=\"cy\" rel=\"alternate\">\n            Cymraeg\n          </a>\n      </li>\n    </ul>\n  </nav>\n\n\n  </div>\n\n  </section>"
+        },
+        {
+            "name": "with language switcher right-aligned",
+            "options": {
+                "serviceName": "Apply for a juggling license",
+                "serviceUrl": "#/",
+                "navigation": [
+                    {
+                        "href": "#/1",
+                        "text": "Navigation item 1"
+                    },
+                    {
+                        "href": "#/2",
+                        "text": "Navigation item 2"
+                    }
+                ],
+                "languageSwitch": {
+                    "currentLanguage": "en",
+                    "englishHref": "/en",
+                    "welshHref": "/cy",
+                    "classes": "govuk-language-switcher--right-align"
+                }
+            },
+            "hidden": false,
+            "description": "",
+            "pageTemplateOptions": {},
+            "screenshot": false,
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Apply for a juggling license\n            </a>\n        </span>\n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n          <nav class=\"govuk-language-switcher govuk-language-switcher-right govuk-language-switcher--right-align\" aria-label=\"Language\">\n    <ul class=\"govuk-language-switcher__list\">\n      <li class=\"govuk-language-switcher__item govuk-language-switcher__item--current\">\n          <span class=\"govuk-service-navigation__text govuk-language-switcher__text\" lang=\"en\" aria-current=\"page\">\n            English\n          </span>\n      </li>\n      <li class=\"govuk-language-switcher__item\">\n          <a class=\"govuk-service-navigation__link govuk-language-switcher__link\" href=\"/cy\" hreflang=\"cy\" lang=\"cy\" rel=\"alternate\">\n            Cymraeg\n          </a>\n      </li>\n    </ul>\n  </nav>\n\n    </div>\n\n    \n  </div>\n\n  </section>"
+        },
+        {
+            "name": "with language switcher responsive",
+            "options": {
+                "serviceName": "Apply for a juggling license",
+                "serviceUrl": "#/",
+                "navigation": [
+                    {
+                        "href": "#/1",
+                        "text": "Navigation item 1"
+                    },
+                    {
+                        "href": "#/2",
+                        "text": "Navigation item 2"
+                    }
+                ],
+                "languageSwitch": {
+                    "currentLanguage": "en",
+                    "classes": "govuk-language-switcher-responsive",
+                    "items": [
+                        {
+                            "code": "en",
+                            "text": "English",
+                            "href": "/en"
+                        },
+                        {
+                            "code": "cy",
+                            "text": "Cymraeg",
+                            "href": "/cy"
+                        },
+                        {
+                            "code": "fr",
+                            "text": "Francais",
+                            "href": "/fr"
+                        },
+                        {
+                            "code": "de",
+                            "text": "Deutsch",
+                            "href": "/de"
+                        },
+                        {
+                            "code": "es",
+                            "text": "Espanol",
+                            "href": "/es"
+                        },
+                        {
+                            "code": "it",
+                            "text": "Italiano",
+                            "href": "/it"
+                        },
+                        {
+                            "code": "pt",
+                            "text": "Portugues",
+                            "href": "/pt"
+                        },
+                        {
+                            "code": "nl",
+                            "text": "Nederlands",
+                            "href": "/nl"
+                        },
+                        {
+                            "code": "pl",
+                            "text": "Polski",
+                            "href": "/pl"
+                        },
+                        {
+                            "code": "ga",
+                            "text": "Gaeilge",
+                            "href": "/ga"
+                        }
+                    ]
+                }
+            },
+            "hidden": false,
+            "description": "",
+            "pageTemplateOptions": {},
+            "screenshot": false,
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Apply for a juggling license\n            </a>\n        </span>\n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n            <nav class=\"govuk-language-switcher govuk-language-switcher-responsive govuk-language-switcher-responsive\" aria-label=\"Language\">\n    <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-language-switcher__toggle govuk-js-service-navigation-toggle\" aria-controls=\"language-switcher-navigation\" hidden aria-hidden=\"true\">\n      Language\n    </button>\n    <ul class=\"govuk-language-switcher__list\" id=\"language-switcher-navigation\">\n        <li class=\"govuk-language-switcher__item govuk-language-switcher__item--current\">\n            <span class=\"govuk-service-navigation__text govuk-language-switcher__text\" lang=\"en\" aria-current=\"page\">\n              English\n            </span>\n        </li>\n        <li class=\"govuk-language-switcher__item\">\n            <a class=\"govuk-service-navigation__link govuk-language-switcher__link\" href=\"/cy\" hreflang=\"cy\" lang=\"cy\" rel=\"alternate\">\n              Cymraeg\n            </a>\n        </li>\n        <li class=\"govuk-language-switcher__item\">\n            <a class=\"govuk-service-navigation__link govuk-language-switcher__link\" href=\"/fr\" hreflang=\"fr\" lang=\"fr\" rel=\"alternate\">\n              Francais\n            </a>\n        </li>\n        <li class=\"govuk-language-switcher__item\">\n            <a class=\"govuk-service-navigation__link govuk-language-switcher__link\" href=\"/de\" hreflang=\"de\" lang=\"de\" rel=\"alternate\">\n              Deutsch\n            </a>\n        </li>\n        <li class=\"govuk-language-switcher__item\">\n            <a class=\"govuk-service-navigation__link govuk-language-switcher__link\" href=\"/es\" hreflang=\"es\" lang=\"es\" rel=\"alternate\">\n              Espanol\n            </a>\n        </li>\n        <li class=\"govuk-language-switcher__item\">\n            <a class=\"govuk-service-navigation__link govuk-language-switcher__link\" href=\"/it\" hreflang=\"it\" lang=\"it\" rel=\"alternate\">\n              Italiano\n            </a>\n        </li>\n        <li class=\"govuk-language-switcher__item\">\n            <a class=\"govuk-service-navigation__link govuk-language-switcher__link\" href=\"/pt\" hreflang=\"pt\" lang=\"pt\" rel=\"alternate\">\n              Portugues\n            </a>\n        </li>\n        <li class=\"govuk-language-switcher__item\">\n            <a class=\"govuk-service-navigation__link govuk-language-switcher__link\" href=\"/nl\" hreflang=\"nl\" lang=\"nl\" rel=\"alternate\">\n              Nederlands\n            </a>\n        </li>\n        <li class=\"govuk-language-switcher__item\">\n            <a class=\"govuk-service-navigation__link govuk-language-switcher__link\" href=\"/pl\" hreflang=\"pl\" lang=\"pl\" rel=\"alternate\">\n              Polski\n            </a>\n        </li>\n        <li class=\"govuk-language-switcher__item\">\n            <a class=\"govuk-service-navigation__link govuk-language-switcher__link\" href=\"/ga\" hreflang=\"ga\" lang=\"ga\" rel=\"alternate\">\n              Gaeilge\n            </a>\n        </li>\n    </ul>\n  </nav>\n\n\n  </div>\n\n  </section>"
         },
         {
             "name": "inverse",
@@ -281,13 +442,13 @@
                     }
                 ]
             },
-            "hidden": false,
+            "hidden": true,
             "description": "Service navigation that appears sandwiched between other areas of brand blue, such as the GOV.UK header and a custom page masthead.",
             "pageTemplateOptions": {
                 "bodyClasses": "app-template__body--inverse"
             },
             "screenshot": false,
-            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation govuk-service-navigation--inverse\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Apply for a juggling license\n            </a>\n        </span>\n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item govuk-service-navigation__item--active\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\" aria-current=\"true\">\n                                    \n                  <strong class=\"govuk-service-navigation__active-fallback\">Navigation item 2</strong>\n\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n                                    \nNavigation item 3\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/4\">\n                                    \nNavigation item 4\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </section>"
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation govuk-service-navigation--inverse\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Apply for a juggling license\n            </a>\n        </span>\n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item govuk-service-navigation__item--active\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\" aria-current=\"true\">\n                                    \n                  <strong class=\"govuk-service-navigation__active-fallback\">Navigation item 2</strong>\n\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n                                    \nNavigation item 3\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/4\">\n                                    \nNavigation item 4\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n    \n  </div>\n\n  </section>"
         },
         {
             "name": "with collapseNavigationOnMobile set to false",
@@ -315,11 +476,11 @@
                 ],
                 "collapseNavigationOnMobile": false
             },
-            "hidden": false,
+            "hidden": true,
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Apply for a juggling license\n            </a>\n        </span>\n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item govuk-service-navigation__item--active\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\" aria-current=\"true\">\n                                    \n                  <strong class=\"govuk-service-navigation__active-fallback\">Navigation item 2</strong>\n\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n                                    \nNavigation item 3\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/4\">\n                                    \nNavigation item 4\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </section>"
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Apply for a juggling license\n            </a>\n        </span>\n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item govuk-service-navigation__item--active\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\" aria-current=\"true\">\n                                    \n                  <strong class=\"govuk-service-navigation__active-fallback\">Navigation item 2</strong>\n\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n                                    \nNavigation item 3\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/4\">\n                                    \nNavigation item 4\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n    \n  </div>\n\n  </section>"
         },
         {
             "name": "with a single navigation item",
@@ -333,11 +494,11 @@
                     }
                 ]
             },
-            "hidden": false,
+            "hidden": true,
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Apply for a juggling license\n            </a>\n        </span>\n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nLog out\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </section>"
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Apply for a juggling license\n            </a>\n        </span>\n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nLog out\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n    \n  </div>\n\n  </section>"
         },
         {
             "name": "with a single navigation item and collapseNavigationOnMobile set to true",
@@ -352,11 +513,11 @@
                 ],
                 "collapseNavigationOnMobile": true
             },
-            "hidden": false,
+            "hidden": true,
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Apply for a juggling license\n            </a>\n        </span>\n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nLog out\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </section>"
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Apply for a juggling license\n            </a>\n        </span>\n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nLog out\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n    \n  </div>\n\n  </section>"
         },
         {
             "name": "with no options set",
@@ -365,7 +526,7 @@
             "description": "If no serviceName or navigation is set, don't render anything.",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n    </div>\n\n    </div>\n\n  </div>"
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n\n    </div>\n\n    \n  </div>\n\n  </div>"
         },
         {
             "name": "attributes",
@@ -380,7 +541,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\" data-foo=\"bar\" data-pika=\"chu\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <span class=\"govuk-service-navigation__text\">Service name</span>\n        </span>\n\n      \n    </div>\n\n    </div>\n\n  </section>"
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\" data-foo=\"bar\" data-pika=\"chu\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <span class=\"govuk-service-navigation__text\">Service name</span>\n        </span>\n\n      \n\n    </div>\n\n    \n  </div>\n\n  </section>"
         },
         {
             "name": "classes",
@@ -392,7 +553,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation app-my-curious-custom-class\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <span class=\"govuk-service-navigation__text\">Service name</span>\n        </span>\n\n      \n    </div>\n\n    </div>\n\n  </section>"
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation app-my-curious-custom-class\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <span class=\"govuk-service-navigation__text\">Service name</span>\n        </span>\n\n      \n\n    </div>\n\n    \n  </div>\n\n  </section>"
         },
         {
             "name": "with custom aria-label",
@@ -404,7 +565,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<section aria-label=\"Service name and nav\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <span class=\"govuk-service-navigation__text\">Service name</span>\n        </span>\n\n      \n    </div>\n\n    </div>\n\n  </section>"
+            "html": "<section aria-label=\"Service name and nav\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <span class=\"govuk-service-navigation__text\">Service name</span>\n        </span>\n\n      \n\n    </div>\n\n    \n  </div>\n\n  </section>"
         },
         {
             "name": "with custom navigation toggle text",
@@ -425,7 +586,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Enter the NavZone\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Enter the NavZone\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Enter the NavZone\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Enter the NavZone\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n    \n  </div>\n\n  </div>"
         },
         {
             "name": "with custom navigation toggle label",
@@ -446,7 +607,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" aria-label=\"Enter the NavZone\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" aria-label=\"Enter the NavZone\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n    \n  </div>\n\n  </div>"
         },
         {
             "name": "with identical navigation toggle text and label",
@@ -468,7 +629,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Enter the NavZone\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Enter the NavZone\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Enter the NavZone\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Enter the NavZone\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n    \n  </div>\n\n  </div>"
         },
         {
             "name": "with custom navigation label",
@@ -489,7 +650,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Main navigation\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Main navigation\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n    \n  </div>\n\n  </div>"
         },
         {
             "name": "with custom navigation toggle text and navigation label",
@@ -511,7 +672,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"The NavZone\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Enter the NavZone\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"The NavZone\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Enter the NavZone\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n    \n  </div>\n\n  </div>"
         },
         {
             "name": "with custom navigation classes",
@@ -532,7 +693,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper app-my-neat-navigation-class\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper app-my-neat-navigation-class\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n    \n  </div>\n\n  </div>"
         },
         {
             "name": "with custom navigation ID",
@@ -553,7 +714,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"main-nav\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"main-nav\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"main-nav\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"main-nav\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n    \n  </div>\n\n  </div>"
         },
         {
             "name": "with navigation having empty values",
@@ -577,7 +738,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n    \n  </div>\n\n  </div>"
         },
         {
             "name": "with navigation having only empty values",
@@ -593,7 +754,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n    </div>\n\n    </div>\n\n  </div>"
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n\n    </div>\n\n    \n  </div>\n\n  </div>"
         },
         {
             "name": "with navigation being an empty array",
@@ -604,7 +765,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n    </div>\n\n    </div>\n\n  </div>"
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n\n    </div>\n\n    \n  </div>\n\n  </div>"
         },
         {
             "name": "with navigation with an active item",
@@ -633,7 +794,7 @@
             "description": "The active item indicates that the user is within that section, but not on the exact page being linked. It looks the same as a current item, but marks this item as an ancestor to the one the user is viewing in ARIA (e.g. a parent section).",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item govuk-service-navigation__item--active\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\" aria-current=\"true\">\n                                    \n                  <strong class=\"govuk-service-navigation__active-fallback\">Navigation item 2</strong>\n\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n                                    \nNavigation item 3\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/4\">\n                                    \nNavigation item 4\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item govuk-service-navigation__item--active\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\" aria-current=\"true\">\n                                    \n                  <strong class=\"govuk-service-navigation__active-fallback\">Navigation item 2</strong>\n\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n                                    \nNavigation item 3\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/4\">\n                                    \nNavigation item 4\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n\n    </div>\n\n    \n  </div>\n\n  </div>"
         },
         {
             "name": "with slotted content",
@@ -649,7 +810,7 @@
             "description": "",
             "pageTemplateOptions": {},
             "screenshot": false,
-            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div>[start]</div><div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            <li>[navigation start]</li>\n            <li>[navigation end]</li></ul>\n        </nav>\n    </div>\n\n    <div>[end]</div></div>\n\n  </section>"
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div>[start]</div><div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            <li>[navigation start]</li>\n            <li>[navigation end]</li></ul>\n        </nav>\n\n    </div>\n\n    <div>[end]</div>\n  </div>\n\n  </section>"
         }
     ],
     "previewLayout": "full-width"
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/macro-options.json b/packages/govuk-frontend/dist/govuk/components/service-navigation/macro-options.json
index 86b04adac..e9fc1c4e7 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/macro-options.json
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/macro-options.json
@@ -140,5 +140,99 @@
                 "description": "HTML injected after the last list item in the navigation list. Requires `navigation` to be set."
             }
         ]
+    },
+    {
+        "name": "languageSwitch",
+        "type": "object",
+        "required": false,
+        "description": "Language switch links shown alongside the service navigation.",
+        "params": [
+            {
+                "name": "currentLanguage",
+                "type": "string",
+                "required": false,
+                "description": "The current language code. Use `en` for English or `cy` for Welsh. Defaults to `en`."
+            },
+            {
+                "name": "englishHref",
+                "type": "string",
+                "required": false,
+                "description": "The URL for the English language link. Defaults to `#`."
+            },
+            {
+                "name": "welshHref",
+                "type": "string",
+                "required": false,
+                "description": "The URL for the Welsh language link. Defaults to `#`."
+            },
+            {
+                "name": "englishText",
+                "type": "string",
+                "required": false,
+                "description": "The text for the English language link. Defaults to `English`."
+            },
+            {
+                "name": "welshText",
+                "type": "string",
+                "required": false,
+                "description": "The text for the Welsh language link. Defaults to `Cymraeg`."
+            },
+            {
+                "name": "ariaLabel",
+                "type": "string",
+                "required": false,
+                "description": "The aria-label for the language switch navigation. Defaults to `Language`."
+            },
+            {
+                "name": "classes",
+                "type": "string",
+                "required": false,
+                "description": "Classes to add to the language switch navigation. Use `govuk-language-switcher--right-align` for the right-aligned variant or `govuk-language-switcher-responsive` for the responsive toggle variant."
+            },
+            {
+                "name": "navigationId",
+                "type": "string",
+                "required": false,
+                "description": "The ID used to associate the responsive language toggle with the language switch list. Defaults to `language-switcher-navigation`."
+            },
+            {
+                "name": "items",
+                "type": "array",
+                "required": false,
+                "description": "Language items to render in the responsive variant. If omitted, the component falls back to English and Welsh.",
+                "params": [
+                    {
+                        "name": "code",
+                        "type": "string",
+                        "required": true,
+                        "description": "The language code used for `lang`, `hreflang`, and current-language matching."
+                    },
+                    {
+                        "name": "text",
+                        "type": "string",
+                        "required": true,
+                        "description": "The visible language name."
+                    },
+                    {
+                        "name": "href",
+                        "type": "string",
+                        "required": false,
+                        "description": "The URL for the language link. Ignored for the current language."
+                    }
+                ]
+            },
+            {
+                "name": "showIcon",
+                "type": "boolean",
+                "required": false,
+                "description": "If `true`, shows a globe icon at the start of the language switcher. Defaults to `false`."
+            },
+            {
+                "name": "attributes",
+                "type": "object",
+                "required": false,
+                "description": "HTML attributes (for example, data attributes) to add to the language switch navigation."
+            }
+        ]
     }
 ]
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.js b/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.js
index 1b52962af..3e2951c9b 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.js
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.js
@@ -160,33 +160,38 @@
      */
     constructor($root) {
       super($root);
-      this.$menuButton = void 0;
-      this.$menu = void 0;
-      this.menuIsOpen = false;
+      this.controlledMenus = [];
       this.mql = null;
-      const $menuButton = this.$root.querySelector('.govuk-js-service-navigation-toggle');
-      if (!$menuButton) {
+      const $menuButtons = this.$root.querySelectorAll('.govuk-js-service-navigation-toggle');
+      if ($menuButtons.length === 0) {
         return this;
       }
-      const menuId = $menuButton.getAttribute('aria-controls');
-      if (!menuId) {
-        throw new ElementError({
-          component: ServiceNavigation,
-          identifier: 'Navigation button (`<button class="govuk-js-service-navigation-toggle">`) attribute (`aria-controls`)'
-        });
-      }
-      const $menu = document.getElementById(menuId);
-      if (!$menu) {
-        throw new ElementError({
-          component: ServiceNavigation,
-          element: $menu,
-          identifier: `Navigation (\`<ul id="${menuId}">\`)`
-        });
-      }
-      this.$menu = $menu;
-      this.$menuButton = $menuButton;
+      this.controlledMenus = Array.from($menuButtons).map($menuButton => {
+        const menuId = $menuButton.getAttribute('aria-controls');
+        if (!menuId) {
+          throw new ElementError({
+            component: ServiceNavigation,
+            identifier: 'Navigation button (`<button class="govuk-js-service-navigation-toggle">`) attribute (`aria-controls`)'
+          });
+        }
+        const $menu = document.getElementById(menuId);
+        if (!$menu) {
+          throw new ElementError({
+            component: ServiceNavigation,
+            element: $menu,
+            identifier: `Navigation (\`<ul id="${menuId}">\`)`
+          });
+        }
+        return {
+          $menu,
+          $menuButton,
+          menuIsOpen: false
+        };
+      });
       this.setupResponsiveChecks();
-      this.$menuButton.addEventListener('click', () => this.handleMenuButtonClick());
+      for (const controlledMenu of this.controlledMenus) {
+        controlledMenu.$menuButton.addEventListener('click', () => this.handleMenuButtonClick(controlledMenu));
+      }
     }
     setupResponsiveChecks() {
       const breakpoint = getBreakpoint('tablet');
@@ -205,24 +210,26 @@
       this.checkMode();
     }
     checkMode() {
-      if (!this.mql || !this.$menu || !this.$menuButton) {
+      if (!this.mql) {
         return;
       }
-      if (this.mql.matches) {
-        this.$menu.removeAttribute('hidden');
-        setAttributes(this.$menuButton, attributesForHidingButton);
-      } else {
-        removeAttributes(this.$menuButton, Object.keys(attributesForHidingButton));
-        this.$menuButton.setAttribute('aria-expanded', this.menuIsOpen.toString());
-        if (this.menuIsOpen) {
-          this.$menu.removeAttribute('hidden');
+      for (const controlledMenu of this.controlledMenus) {
+        if (this.mql.matches) {
+          controlledMenu.$menu.removeAttribute('hidden');
+          setAttributes(controlledMenu.$menuButton, attributesForHidingButton);
         } else {
-          this.$menu.setAttribute('hidden', '');
+          removeAttributes(controlledMenu.$menuButton, Object.keys(attributesForHidingButton));
+          controlledMenu.$menuButton.setAttribute('aria-expanded', controlledMenu.menuIsOpen.toString());
+          if (controlledMenu.menuIsOpen) {
+            controlledMenu.$menu.removeAttribute('hidden');
+          } else {
+            controlledMenu.$menu.setAttribute('hidden', '');
+          }
         }
       }
     }
-    handleMenuButtonClick() {
-      this.menuIsOpen = !this.menuIsOpen;
+    handleMenuButtonClick(controlledMenu) {
+      controlledMenu.menuIsOpen = !controlledMenu.menuIsOpen;
       this.checkMode();
     }
   }
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.mjs b/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.mjs
index a77be4f2c..b03d69473 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.mjs
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.mjs
@@ -154,33 +154,38 @@ class ServiceNavigation extends Component {
    */
   constructor($root) {
     super($root);
-    this.$menuButton = void 0;
-    this.$menu = void 0;
-    this.menuIsOpen = false;
+    this.controlledMenus = [];
     this.mql = null;
-    const $menuButton = this.$root.querySelector('.govuk-js-service-navigation-toggle');
-    if (!$menuButton) {
+    const $menuButtons = this.$root.querySelectorAll('.govuk-js-service-navigation-toggle');
+    if ($menuButtons.length === 0) {
       return this;
     }
-    const menuId = $menuButton.getAttribute('aria-controls');
-    if (!menuId) {
-      throw new ElementError({
-        component: ServiceNavigation,
-        identifier: 'Navigation button (`<button class="govuk-js-service-navigation-toggle">`) attribute (`aria-controls`)'
-      });
-    }
-    const $menu = document.getElementById(menuId);
-    if (!$menu) {
-      throw new ElementError({
-        component: ServiceNavigation,
-        element: $menu,
-        identifier: `Navigation (\`<ul id="${menuId}">\`)`
-      });
-    }
-    this.$menu = $menu;
-    this.$menuButton = $menuButton;
+    this.controlledMenus = Array.from($menuButtons).map($menuButton => {
+      const menuId = $menuButton.getAttribute('aria-controls');
+      if (!menuId) {
+        throw new ElementError({
+          component: ServiceNavigation,
+          identifier: 'Navigation button (`<button class="govuk-js-service-navigation-toggle">`) attribute (`aria-controls`)'
+        });
+      }
+      const $menu = document.getElementById(menuId);
+      if (!$menu) {
+        throw new ElementError({
+          component: ServiceNavigation,
+          element: $menu,
+          identifier: `Navigation (\`<ul id="${menuId}">\`)`
+        });
+      }
+      return {
+        $menu,
+        $menuButton,
+        menuIsOpen: false
+      };
+    });
     this.setupResponsiveChecks();
-    this.$menuButton.addEventListener('click', () => this.handleMenuButtonClick());
+    for (const controlledMenu of this.controlledMenus) {
+      controlledMenu.$menuButton.addEventListener('click', () => this.handleMenuButtonClick(controlledMenu));
+    }
   }
   setupResponsiveChecks() {
     const breakpoint = getBreakpoint('tablet');
@@ -199,24 +204,26 @@ class ServiceNavigation extends Component {
     this.checkMode();
   }
   checkMode() {
-    if (!this.mql || !this.$menu || !this.$menuButton) {
+    if (!this.mql) {
       return;
     }
-    if (this.mql.matches) {
-      this.$menu.removeAttribute('hidden');
-      setAttributes(this.$menuButton, attributesForHidingButton);
-    } else {
-      removeAttributes(this.$menuButton, Object.keys(attributesForHidingButton));
-      this.$menuButton.setAttribute('aria-expanded', this.menuIsOpen.toString());
-      if (this.menuIsOpen) {
-        this.$menu.removeAttribute('hidden');
+    for (const controlledMenu of this.controlledMenus) {
+      if (this.mql.matches) {
+        controlledMenu.$menu.removeAttribute('hidden');
+        setAttributes(controlledMenu.$menuButton, attributesForHidingButton);
       } else {
-        this.$menu.setAttribute('hidden', '');
+        removeAttributes(controlledMenu.$menuButton, Object.keys(attributesForHidingButton));
+        controlledMenu.$menuButton.setAttribute('aria-expanded', controlledMenu.menuIsOpen.toString());
+        if (controlledMenu.menuIsOpen) {
+          controlledMenu.$menu.removeAttribute('hidden');
+        } else {
+          controlledMenu.$menu.setAttribute('hidden', '');
+        }
       }
     }
   }
-  handleMenuButtonClick() {
-    this.menuIsOpen = !this.menuIsOpen;
+  handleMenuButtonClick(controlledMenu) {
+    controlledMenu.menuIsOpen = !controlledMenu.menuIsOpen;
     this.checkMode();
   }
 }
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.mjs b/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.mjs
index 5f1458b93..a20a0f01c 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.mjs
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.mjs
@@ -13,33 +13,38 @@ class ServiceNavigation extends Component {
    */
   constructor($root) {
     super($root);
-    this.$menuButton = void 0;
-    this.$menu = void 0;
-    this.menuIsOpen = false;
+    this.controlledMenus = [];
     this.mql = null;
-    const $menuButton = this.$root.querySelector('.govuk-js-service-navigation-toggle');
-    if (!$menuButton) {
+    const $menuButtons = this.$root.querySelectorAll('.govuk-js-service-navigation-toggle');
+    if ($menuButtons.length === 0) {
       return this;
     }
-    const menuId = $menuButton.getAttribute('aria-controls');
-    if (!menuId) {
-      throw new ElementError({
-        component: ServiceNavigation,
-        identifier: 'Navigation button (`<button class="govuk-js-service-navigation-toggle">`) attribute (`aria-controls`)'
-      });
-    }
-    const $menu = document.getElementById(menuId);
-    if (!$menu) {
-      throw new ElementError({
-        component: ServiceNavigation,
-        element: $menu,
-        identifier: `Navigation (\`<ul id="${menuId}">\`)`
-      });
-    }
-    this.$menu = $menu;
-    this.$menuButton = $menuButton;
+    this.controlledMenus = Array.from($menuButtons).map($menuButton => {
+      const menuId = $menuButton.getAttribute('aria-controls');
+      if (!menuId) {
+        throw new ElementError({
+          component: ServiceNavigation,
+          identifier: 'Navigation button (`<button class="govuk-js-service-navigation-toggle">`) attribute (`aria-controls`)'
+        });
+      }
+      const $menu = document.getElementById(menuId);
+      if (!$menu) {
+        throw new ElementError({
+          component: ServiceNavigation,
+          element: $menu,
+          identifier: `Navigation (\`<ul id="${menuId}">\`)`
+        });
+      }
+      return {
+        $menu,
+        $menuButton,
+        menuIsOpen: false
+      };
+    });
     this.setupResponsiveChecks();
-    this.$menuButton.addEventListener('click', () => this.handleMenuButtonClick());
+    for (const controlledMenu of this.controlledMenus) {
+      controlledMenu.$menuButton.addEventListener('click', () => this.handleMenuButtonClick(controlledMenu));
+    }
   }
   setupResponsiveChecks() {
     const breakpoint = getBreakpoint('tablet');
@@ -58,24 +63,26 @@ class ServiceNavigation extends Component {
     this.checkMode();
   }
   checkMode() {
-    if (!this.mql || !this.$menu || !this.$menuButton) {
+    if (!this.mql) {
       return;
     }
-    if (this.mql.matches) {
-      this.$menu.removeAttribute('hidden');
-      setAttributes(this.$menuButton, attributesForHidingButton);
-    } else {
-      removeAttributes(this.$menuButton, Object.keys(attributesForHidingButton));
-      this.$menuButton.setAttribute('aria-expanded', this.menuIsOpen.toString());
-      if (this.menuIsOpen) {
-        this.$menu.removeAttribute('hidden');
+    for (const controlledMenu of this.controlledMenus) {
+      if (this.mql.matches) {
+        controlledMenu.$menu.removeAttribute('hidden');
+        setAttributes(controlledMenu.$menuButton, attributesForHidingButton);
       } else {
-        this.$menu.setAttribute('hidden', '');
+        removeAttributes(controlledMenu.$menuButton, Object.keys(attributesForHidingButton));
+        controlledMenu.$menuButton.setAttribute('aria-expanded', controlledMenu.menuIsOpen.toString());
+        if (controlledMenu.menuIsOpen) {
+          controlledMenu.$menu.removeAttribute('hidden');
+        } else {
+          controlledMenu.$menu.setAttribute('hidden', '');
+        }
       }
     }
   }
-  handleMenuButtonClick() {
-    this.menuIsOpen = !this.menuIsOpen;
+  handleMenuButtonClick(controlledMenu) {
+    controlledMenu.menuIsOpen = !controlledMenu.menuIsOpen;
     this.checkMode();
   }
 }
diff --git a/packages/govuk-frontend/dist/govuk/components/test-service-navigation/README.md b/packages/govuk-frontend/dist/govuk/components/test-service-navigation/README.md
new file mode 100644
index 000000000..dc62afa37
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/test-service-navigation/README.md
@@ -0,0 +1,3 @@
+# Test service navigation
+
+This is a spike component used to test integrating the standalone language-switcher component into a service-navigation-like layout.
diff --git a/packages/govuk-frontend/dist/govuk/components/test-service-navigation/_index.import.scss b/packages/govuk-frontend/dist/govuk/components/test-service-navigation/_index.import.scss
new file mode 100644
index 000000000..e74fc2ecc
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/test-service-navigation/_index.import.scss
@@ -0,0 +1,2 @@
+@import "test-service-navigation";
+
diff --git a/packages/govuk-frontend/dist/govuk/components/test-service-navigation/_index.scss b/packages/govuk-frontend/dist/govuk/components/test-service-navigation/_index.scss
new file mode 100644
index 000000000..8be2e75f1
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/test-service-navigation/_index.scss
@@ -0,0 +1,5 @@
+@use "../../custom-properties";
+@use "mixin";
+
+@include mixin.styles;
+
diff --git a/packages/govuk-frontend/dist/govuk/components/test-service-navigation/_mixin.scss b/packages/govuk-frontend/dist/govuk/components/test-service-navigation/_mixin.scss
new file mode 100644
index 000000000..a7db3baa2
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/test-service-navigation/_mixin.scss
@@ -0,0 +1,9 @@
+/// @group components/test-service-navigation
+/// @access private
+@mixin styles {
+  // Test component wrapper class for component discovery and optional overrides.
+  .govuk-test-service-navigation {
+    display: block;
+  }
+}
+
diff --git a/packages/govuk-frontend/dist/govuk/components/test-service-navigation/_test-service-navigation.import.scss b/packages/govuk-frontend/dist/govuk/components/test-service-navigation/_test-service-navigation.import.scss
new file mode 100644
index 000000000..ef4f2e98b
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/test-service-navigation/_test-service-navigation.import.scss
@@ -0,0 +1,8 @@
+@use "mixin";
+
+@import "../../base";
+
+@include govuk-exports("govuk/component/test-service-navigation") {
+  @include mixin.styles;
+}
+
diff --git a/packages/govuk-frontend/dist/govuk/components/test-service-navigation/fixtures.json b/packages/govuk-frontend/dist/govuk/components/test-service-navigation/fixtures.json
new file mode 100644
index 000000000..d82743865
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/test-service-navigation/fixtures.json
@@ -0,0 +1,54 @@
+{
+    "component": "test-service-navigation",
+    "fixtures": [
+        {
+            "name": "default",
+            "options": {
+                "serviceName": "Apply for a juggling license",
+                "serviceUrl": "#/",
+                "navigation": [
+                    {
+                        "href": "#/1",
+                        "text": "Navigation item 1"
+                    },
+                    {
+                        "href": "#/2",
+                        "text": "Navigation item 2"
+                    }
+                ],
+                "languageSwitch": {
+                    "currentLanguage": "en",
+                    "showIcon": true,
+                    "classes": "govuk-language-switcher-responsive",
+                    "items": [
+                        {
+                            "code": "en",
+                            "text": "English",
+                            "href": "/en"
+                        },
+                        {
+                            "code": "cy",
+                            "text": "Cymraeg",
+                            "href": "/cy"
+                        },
+                        {
+                            "code": "fr",
+                            "text": "Francais",
+                            "href": "/fr"
+                        }
+                    ]
+                }
+            },
+            "hidden": false,
+            "description": "",
+            "pageTemplateOptions": {},
+            "screenshot": {
+                "variants": [
+                    "default",
+                    "no-js"
+                ]
+            },
+            "html": "<section aria-label=\"Service information\" class=\"govuk-test-service-navigation govuk-service-navigation\" data-module=\"govuk-service-navigation\">\n  <div class=\"govuk-width-container\">\n    <div class=\"govuk-service-navigation__container\">\n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Apply for a juggling license\n            </a>\n        </span>\n\n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n            <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n              Menu\n            </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\">\n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                      Navigation item 1\n                  </a>\n              </li>\n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                      Navigation item 2\n                  </a>\n              </li>\n          </ul>\n        </nav>\n\n    </div>\n\n      <nav class=\"govuk-language-switcher govuk-language-switcher-responsive govuk-language-switcher-responsive govuk-language-switcher--collapsible\" aria-label=\"Language\" data-module=\"govuk-language-switcher\">\n    <button type=\"button\" class=\"govuk-language-switcher__toggle govuk-js-language-switcher-toggle\" aria-controls=\"language-switcher-navigation\" hidden aria-hidden=\"true\">\n          <span class=\"govuk-language-switcher__icon\" aria-hidden=\"true\">\n    <svg class=\"govuk-language-switcher__icon-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20\" width=\"20\" aria-hidden=\"true\" focusable=\"false\" viewBox=\"0 0 20 20\">\n      <circle cx=\"10\" cy=\"10\" r=\"8\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n      <ellipse cx=\"10\" cy=\"10\" rx=\"3.5\" ry=\"8\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n      <line x1=\"2\" y1=\"10\" x2=\"18\" y2=\"10\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n      <path d=\"M3.5 6.5h13M3.5 13.5h13\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n    </svg>\n  </span>\n\n      Language\n    </button>\n  <ul class=\"govuk-language-switcher__list\" id=\"language-switcher-navigation\">\n      <li class=\"govuk-language-switcher__item govuk-language-switcher__item--icon\" aria-hidden=\"true\">\n          <span class=\"govuk-language-switcher__icon\" aria-hidden=\"true\">\n    <svg class=\"govuk-language-switcher__icon-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20\" width=\"20\" aria-hidden=\"true\" focusable=\"false\" viewBox=\"0 0 20 20\">\n      <circle cx=\"10\" cy=\"10\" r=\"8\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n      <ellipse cx=\"10\" cy=\"10\" rx=\"3.5\" ry=\"8\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n      <line x1=\"2\" y1=\"10\" x2=\"18\" y2=\"10\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n      <path d=\"M3.5 6.5h13M3.5 13.5h13\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"1.5\" />\n    </svg>\n  </span>\n\n      </li>\n<li class=\"govuk-language-switcher__item govuk-language-switcher__item--current\">\n          <span class=\"govuk-language-switcher__text\" lang=\"en\" aria-current=\"page\">\n            English\n          </span>\n      </li>\n<li class=\"govuk-language-switcher__item\">\n          <a class=\"govuk-language-switcher__link\" href=\"/cy\" hreflang=\"cy\" lang=\"cy\" rel=\"alternate\">\n            Cymraeg\n          </a>\n      </li>\n<li class=\"govuk-language-switcher__item\">\n          <a class=\"govuk-language-switcher__link\" href=\"/fr\" hreflang=\"fr\" lang=\"fr\" rel=\"alternate\">\n            Francais\n          </a>\n      </li>\n  </ul>\n</nav>\n\n  </div>\n</section>"
+        }
+    ]
+}
diff --git a/packages/govuk-frontend/dist/govuk/components/test-service-navigation/macro-options.json b/packages/govuk-frontend/dist/govuk/components/test-service-navigation/macro-options.json
new file mode 100644
index 000000000..21e720f32
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/test-service-navigation/macro-options.json
@@ -0,0 +1,122 @@
+[
+    {
+        "name": "classes",
+        "type": "string",
+        "required": false,
+        "description": "Classes to add to the service navigation container."
+    },
+    {
+        "name": "attributes",
+        "type": "object",
+        "required": false,
+        "description": "HTML attributes to add to the service navigation container."
+    },
+    {
+        "name": "serviceName",
+        "type": "string",
+        "required": false,
+        "description": "The name of your service."
+    },
+    {
+        "name": "serviceUrl",
+        "type": "string",
+        "required": false,
+        "description": "The homepage of your service."
+    },
+    {
+        "name": "navigation",
+        "type": "array",
+        "required": false,
+        "description": "Navigation items.",
+        "params": [
+            {
+                "name": "text",
+                "type": "string",
+                "required": true,
+                "description": "Link text."
+            },
+            {
+                "name": "href",
+                "type": "string",
+                "required": false,
+                "description": "Link URL."
+            },
+            {
+                "name": "active",
+                "type": "boolean",
+                "required": false,
+                "description": "Whether this item is active."
+            },
+            {
+                "name": "current",
+                "type": "boolean",
+                "required": false,
+                "description": "Whether this item is the current page."
+            },
+            {
+                "name": "attributes",
+                "type": "object",
+                "required": false,
+                "description": "HTML attributes for the navigation link."
+            }
+        ]
+    },
+    {
+        "name": "languageSwitch",
+        "type": "object",
+        "required": false,
+        "description": "Language switcher options using the new language-switcher component model.",
+        "params": [
+            {
+                "name": "currentLanguage",
+                "type": "string",
+                "required": false,
+                "description": "Current language code."
+            },
+            {
+                "name": "classes",
+                "type": "string",
+                "required": false,
+                "description": "Language switcher classes. Use `govuk-language-switcher--right-align` for inline right or `govuk-language-switcher-responsive` to collapse on mobile."
+            },
+            {
+                "name": "navigationId",
+                "type": "string",
+                "required": false,
+                "description": "ID for the language switcher list."
+            },
+            {
+                "name": "showIcon",
+                "type": "boolean",
+                "required": false,
+                "description": "Show a leading globe icon."
+            },
+            {
+                "name": "items",
+                "type": "array",
+                "required": false,
+                "description": "Language options.",
+                "params": [
+                    {
+                        "name": "code",
+                        "type": "string",
+                        "required": true,
+                        "description": "Language code."
+                    },
+                    {
+                        "name": "text",
+                        "type": "string",
+                        "required": true,
+                        "description": "Language name."
+                    },
+                    {
+                        "name": "href",
+                        "type": "string",
+                        "required": false,
+                        "description": "Language URL."
+                    }
+                ]
+            }
+        ]
+    }
+]
diff --git a/packages/govuk-frontend/dist/govuk/init.mjs b/packages/govuk-frontend/dist/govuk/init.mjs
index 120dec104..936845224 100644
--- a/packages/govuk-frontend/dist/govuk/init.mjs
+++ b/packages/govuk-frontend/dist/govuk/init.mjs
@@ -7,6 +7,7 @@ import { Checkboxes } from './components/checkboxes/checkboxes.mjs';
 import { ErrorSummary } from './components/error-summary/error-summary.mjs';
 import { ExitThisPage } from './components/exit-this-page/exit-this-page.mjs';
 import { FileUpload } from './components/file-upload/file-upload.mjs';
+import { LanguageSwitcher } from './components/language-switcher/language-switcher.mjs';
 import { NotificationBanner } from './components/notification-banner/notification-banner.mjs';
 import { PasswordInput } from './components/password-input/password-input.mjs';
 import { Radios } from './components/radios/radios.mjs';
@@ -46,7 +47,7 @@ function initAll(scopeOrConfig = {}) {
     }
     return;
   }
-  const components = [[Accordion, config.accordion], [Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [ExitThisPage, config.exitThisPage], [FileUpload, config.fileUpload], [NotificationBanner, config.notificationBanner], [PasswordInput, config.passwordInput], [Radios], [ServiceNavigation], [SkipLink], [Tabs]];
+  const components = [[Accordion, config.accordion], [Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [ExitThisPage, config.exitThisPage], [FileUpload, config.fileUpload], [LanguageSwitcher], [NotificationBanner, config.notificationBanner], [PasswordInput, config.passwordInput], [Radios], [ServiceNavigation], [SkipLink], [Tabs]];
   components.forEach(([Component, componentConfig]) => {
     createAll(Component, componentConfig, options);
   });

Action run for 4f519a7

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown

📋 Stats

File sizes

File Size Percentage change
dist/govuk-frontend-development.min.css 127.97 KiB 6.8%
dist/govuk-frontend-development.min.js 47.88 KiB 4.2%
packages/govuk-frontend/dist/govuk/all.bundle.js 103.32 KiB 4%
packages/govuk-frontend/dist/govuk/all.bundle.mjs 97.08 KiB 4%
packages/govuk-frontend/dist/govuk/all.mjs 1.31 KiB 7.1%
packages/govuk-frontend/dist/govuk/govuk-frontend.min.css 127.96 KiB 6.8%
packages/govuk-frontend/dist/govuk/govuk-frontend.min.js 47.86 KiB 4.2%
packages/govuk-frontend/dist/govuk/init.mjs 7.36 KiB 1.5%

Modules

File Size (bundled) Percentage change (bundled) Size (minified) Percentage change (bundled)
all.mjs 91.03 KiB 4.2% 45.35 KiB 3.8%
service-navigation.mjs 7.76 KiB 4.7% 3.49 KiB 1.4%
language-switcher.mjs 7.54 KiB New file 3.47 KiB New file

View stats and visualisations on the review app


Action run for 4f519a7

@domoscargin domoscargin linked an issue Jun 3, 2026 that may be closed by this pull request
1 task
@domoscargin domoscargin changed the title [SPIKE][WIP] Test different language switchers in service nav [SPIKE][WIP] Test different language switchers in govuk-frontend Jun 4, 2026
@domoscargin domoscargin force-pushed the spike-language-switch-nav branch from 4203960 to 4f519a7 Compare June 4, 2026 11:51
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-7141 June 4, 2026 11:51 Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SPIKE: Add a language switcher to service navigation

2 participants