Bootstrap, Hugo and how to implement a language switch

I want to implement a Language switch in a website. The language switch should work as a dropdown menu. The website shows the Language switch, but it doesn’t work.

img 1

Here is the navigation:

<nav class="navbar navbar-expand-lg navbar-dark bg-primary shadow-sm fixed-top">
	<div class="container">
		<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
			aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
			<span class="navbar-toggler-icon"></span>
		</button>
		<div class="collapse navbar-collapse" id="navbarSupportedContent">
			<ul class="navbar-nav me-auto mb-2 mb-lg-0">
				{{ range .Site.Menus.main }}
				{{ if .HasChildren }}
				<li class="nav-item dropdown">
					<a class="nav-link dropdown-toggle{{ if $.HasMenuCurrent " main" . }} active{{ end }}" href="#"
						role="button" data-bs-toggle="dropdown" aria-expanded="false">
						{{ .Pre }}<span>{{ .Name }}</span>{{ .Post }}
					</a>
					<ul class="dropdown-menu">
						{{ range .Children }}
						{{ if eq .Params.divider true }}
						<li>
							<hr class="dropdown-divider">
						</li>
						{{ else }}
						<li>
							<a class="dropdown-item{{ if $.IsMenuCurrent " main" . }} active"
								aria-current="page{{ end }}" href="{{ .URL }}">
								{{ .Pre }}<span>{{ .Name }}</span>{{ .Post }}
							</a>
						</li>
						{{ end }}
						{{ end }}
					</ul>
				</li>
				{{ else }}
				<li class="nav-item">
					<a class="nav-link{{ if $.IsMenuCurrent " main" . }} active" aria-current="page{{ end }}"
						href="{{ .URL }}">
						{{ .Pre }}<span>{{ .Name }}</span>{{ .Post }}
					</a>
				</li>
				{{ end }}
				{{ end }}
				<li class="nav-item dropdown">
					<button class="nav-link dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
						<img src="/images/lang.svg" alt="Language">
					</button>
					<ul class="dropdown-menu" aria-labelledby="navbarDropLanguages">
						{{ range $.AllTranslations }}
						<li><a class='dropdown-item {{ if eq .Lang $.Lang }} active {{ end }}'
								href='{{ .RelPermalink }}' hreflang="{{ $.Lang }}"> {{ .Language.LanguageName }} </a>
						</li>
						{{ end }}
					</ul>
			</ul>
			<a class="navbar-brand" href="/">{{ .Site.Title }}<img src="/images/logo.jpg" class="logo"
					alt="{{ .Site.Title }}">
			</a>
		</div>
	</div>
</nav>

The config-yaml has the following entries:

baseURL: https://example.com/
relativeURLs: true
languageCode: en-us
title: Example AG
theme: example

defaultContentLanguage: en
languages:
    en: {weight: 1, languagename: English}
    de: {weight: 2, languagename: Deutsch}

module:
  imports:
    - path: github.com/gohugoio/hugo-mod-bootstrap-scss/v5

markup:
  goldmark:
    renderer:
      unsafe: true

The translation is created with Weblate. German is the preferred language!

de.json

{
	"Mehr lesen": "Mehr lesen",
	"404 Nicht gefunden": "404 Nicht gefunden",
	"Leider konnte die Seite, die Sie aufgerufen haben, nicht gefunden werden.": "Leider konnte die Seite, die Sie aufgerufen haben, nicht gefunden werden."
}

en.json

{
	"Mehr lesen": "Read more",
	"404 Nicht gefunden": "404 Not Found",
	"Leider konnte die Seite, die Sie aufgerufen haben, nicht gefunden werden.": "Sorry, but the page you were trying to access could not be found."
}

My 404 Page as an example

{{define "main"}}
<div class="container">
	<div class="py-5">
		<section class="d-flex flex-column flex-fill align-items-center justify-content-center py-3">
			<h1 class="section-title"> {{ i18n "404 Nicht gefunden" }} </h1>
			<div>
				{{ i18n "Leider konnte die Seite, die Sie aufgerufen haben, nicht gefunden werden." }}
			</div>
		</section>
	</div>
</div>
{{end}}

I suggest that you post a link to your repository. Without context, it’s impossible to see what the HTML is supposed to be doing. How would I know how data-bs-target is used by what component?

OTOH: Hugo is a static site generator. Therefore, a button alone might not be enough to switch the language for the whole site.

Have you import the dropdown JS component?

import "js/bootstrap/src/dropdown";

Here is the link to the Repository.

after the download you need to run

go mod init test
go mod tidy
hugo server

There are several issues of your current implementation.

  1. I’d suggest using js.Build to generate the JS as supposed to use CDN to keep the CSS and JS version to be same, In this case, the CSS is v5.3.0, but the the CDN JS version’s is v5.1.3.

Solution:

// assets/js/main.js
import "js/bootstrap/src/dropdown";
// You can import any required JS components that listed on
// https://github.com/twbs/bootstrap/tree/main/js/src.

And then remove the CDN script from partial and use the js.Build to generate JS.

// layouts/partials/script-footer.html
{{ $js := resources.Get "js/main.js" | js.Build | fingerprint }}
<script type="text/javascript" src="{{ $js.RelPermalink }}" integrity="{{ $js.Data.Integrity }}"></script>
  1. As to the v5.3.1, the dropdown key data attribute is renamed to data-bs-toggle from data-toggle (since v* I don’t remember). Replace the data-toggle="dropdown" to data-bs-toggle="dropdown" then it work.

image

I’ve deleted the repo locally, you need to adjust three files as I mentioned above:

  1. themes/kwpse/assets/js/main.js.
  2. themes/kwpse/layouts/partials/script-footer.html.
  3. themes/kwpse/layouts/partials/navbar.html.
1 Like

It works fine.

Thank you