Language toggle
The language toggle is the EN / FR pair at the right end of the site header. Each option is a plain link to the current page in that language, and the active language is highlighted. It sits in the same visible location on every page — top right, next to search — so readers always know where to switch.
When to use#
- One instance only, rendered by the site header on every page; pages and layouts never add their own
- Two languages, two links — a pair of links is smaller and clearer than a dropdown or radio group, and each option names its language directly
- When the current page has no translation, the option links to that language’s home page instead of a 404 or a disabled control — both options stay operable everywhere
- Not for switching anything other than language; other header actions (search, navigation) have their own components
Implementation#
<nav class="language-switcher" aria-label="Language">
{{ $page := . }}
{{ range hugo.Sites }}
{{ $site := . }}
{{ $translation := where $page.AllTranslations "Lang" $site.Language.Lang }}
{{ $href := $site.Home.RelPermalink }}
{{ with index $translation 0 }}{{ $href = .RelPermalink }}{{ end }}
<a class="language-link {{ if eq $site.Language.Lang $page.Lang }}language-link-active{{ end }}" href="{{ $href }}"{{ if eq $site.Language.Lang $page.Lang }} aria-current="true"{{ end }}>{{ upper $site.Language.Lang }}</a>
{{ end }}
</nav><nav class="language-switcher" aria-label="Language">
<a class="language-link language-link-active" href="/en/docs/site-implementation/components/language-toggle/" aria-current="true">EN</a>
<a class="language-link" href="/fr/docs/site-implementation/components/selecteur-de-langue/">FR</a>
</nav>The switcher lives inline in layouts/partials/header.html, inside the header-actions group, and takes no options. It loops over hugo.Sites, resolves the current page’s translation for each language through AllTranslations, and falls back to that language’s home page when no translation exists. There is no JavaScript and no separate CSS file; styling is the .language-switcher, .language-link, and .language-link-active classes in assets/css/site.css.
Interface manifest
- Kind
- Component
- Category
- Navigation
- Status
- Implemented
- Implementation
- Partial:
layouts/partials/header.htmlCSS:assets/css/site.cssi18n:languageSwitcher - Used by
layouts/partials/header.html- Related interfaces
- Navigation
Accessibility#
- The switcher is a
<nav>landmark, localized through thelanguageSwitcheri18n key, so screen readers can tell it apart from the main navigation - Each option is a plain link whose text names the language (EN, FR) — screen readers identify every option by its link text; this is a nav of links, not a radio group, so no
roleoraria-checkedplumbing is involved - The active language link carries
aria-current="true"alongside thelanguage-link-activeclass, so the current language is announced rather than only styled - Keyboard: Tab reaches each link and Enter follows it — no JavaScript, no custom key handling
- Avoid pointing an option at a 404 or disabling it when no translation exists; the fallback to the language’s home page keeps both options always operable