Broken links in multi language sites when upgrading from 0.91.0

Hey folks I recently inherited a Hugo project that was stuck using the unmaintained klakegg containers and was on version 0.91.0 extended.

We wanted to update this to a more modern version (0.135.0 since I update versions monthly) but ran into some strange problems with how urls for translated pages were handled in links and by hugo serve

When using hugo serve the output indicates the ports have been assigned as expected:

hugo  | Web Server is available at //localhost:1314/ (bind address 0.0.0.0) en
hugo  | Web Server is available at //localhost:1313/ (bind address 0.0.0.0) de
hugo  | Web Server is available at //localhost:1315/ (bind address 0.0.0.0) fr
hugo  | Web Server is available at //localhost:1316/ (bind address 0.0.0.0) nl

But the english pages are actually served on port 1313 but all links still point to 1314 and the the reverse was the case for the german pages

Similarly running a build rather than the local server results in the wrong baseurl for links.

We suspect something in how links are generated is broken by the changes in 112 or 123 related to how language params are accessed or the default link renderer but are not sure how to proceed debugging - can anybody suggest a diagnosis or solution ?

Our config loooks like:

{
  "enableGitInfo": true,
  "disableHugoGeneratorInject": true,
  "markup": {
    "goldmark": {
      "renderer": {
        "unsafe": "true"
      }
    }
  },
  "theme": "2020",
  "title": "Uptrends",
  "DefaultContentLanguage": "en",
  "languages": {
    "de": {
      "languageName": "Deutsch",
      "baseURL": "",
      "languageCode": "de"
    },
    "en": {
      "languageName": "English",
      "baseURL": "",
      "languageCode": "en"
    },
    "fr": {
      "languageName": "Français",
      "baseURL": "",
      "languageCode": "fr"
    },
    "nl": {
      "languageName": "Nederlands",
      "baseURL": "",
      "languageCode": "nl"
    }
  },
  "Params": {
    "de": {
      "hstsImageUrl": "//uptrends.de/img/hsts.png",
      "AnalyticsId": "nope",
      "useNewAnalytics": true,
      "gTagId": "nope"
    },
    "en": {
      "hstsImageUrl": "//uptrends.com/img/hsts.png",
      "AnalyticsId": "nope",
      "useNewAnalytics": true,
      "gTagId": "nope"
    },
    "fr": {
      "hstsImageUrl": "//uptrends.fr/img/hsts.png",
      "AnalyticsId": "nope",
      "useNewAnalytics": true,
      "gTagId": "nope"
    },
    "nl": {
      "hstsImageUrl": "//uptrends.nl/img/hsts.png",
      "AnalyticsId": "nope",
      "useNewAnalytics": true,
      "gTagId": "nope"
    },
    "CheckpointCount": "233"
  },
  }
}

with some menus ommited for simplicity and then a per environment config for baseurls

"languages": {
        "de": {
            "baseURL": "https://www.uptrends.de"
        },
        "en": {
            "baseURL": "https://www.uptrends.com"
        },
        "fr": {
            "baseURL": "https://www.uptrends.fr"
        },
        "nl": {
            "baseURL": "https://www.uptrends.nl"
        }
     }

I’m happy to provide any other info but can’t share the repo directly

Do any of your content files use upper case or mixed case language identifiers in the file name?

No the language ids are always lower case, for example
Content/Www/content/support/kb/alerting/china-India-sms-voice-alert-issues.en.md
Content/Www/content/support/kb/alerting/china-India-sms-voice-alert-issues.fr.md

and we use the translationKeys in frontmatter for matching pages

{
  "hero": {
    "title": "China and India SMS and voice alert issues"
  },
  "title": "China and India SMS and voice alert issues",
  "summary": "Spam filters and do-not-call registries may block alert messages to some regions, so consider these other options for your operators in China or India.  ",
  "url": "/support/kb/alerting/china-india-sms-voice-alert-issues",
  "translationKey": "https://www.uptrends.com/support/kb/alerting/china-india-sms-voice-alert-issues"
}

One thing I noticed, but may not make any difference in your case, is that the baseURLs in your site configuration are blank. That is not a valid value. Set the baseURL to the production URL as described in the documentation:

https://gohugo.io/getting-started/configuration/#baseurl

Since you can’t share your site with us, I created a multilingual multi-host site to use for testing:

git clone --single-branch -b hugo-forum-topic-52077 https://github.com/jmooring/hugo-testing hugo-forum-topic-52077
cd hugo-forum-topic-52077
hugo server

All of the links are correct. There’s obviously something different about your site, perhaps the use of translation keys or setting the url in front matter. Please test the above… perhaps you can identify what’s different.

I will have a look, thanks

Another thing I noticed, which again may not make any difference in your case, is that the front matter url values begin with a slash. They should not, at least for single-host sites. I would get into the habit of omitting the leading slash so that you generate the correct URLs regardless of whether your multilingual site is single-host or multi-host.

https://gohugo.io/content-management/urls/#leading-slashes

So theres a few things I noticed, in your baseof.html

<html lang="{{ site.Language.LanguageCode }}" dir="{{ or site.Language.LanguageDirection `ltr` }}">

vs what we have

<html lang="{{ $.Site.LanguageCode | default "en" }}">

and similarly in language-switcher you have href="{{ .Permalink }}" but in our equivalent we have href="{{ .Language.Params.baseurl }}{{ .RelPermalink }}" but swapping to permalink has no effect on our results

Both are irrelevant, but I would do this in baseof:

<html lang="{{ site.Language.LanguageCode }}" dir="{{ or site.Language.LanguageDirection `ltr` }}">

From the relevant documentation:

The language code from the site configuration. Falls back to Lang if not defined.

Also, this doesn’t make sense to me:

{{ .Language.Params.baseurl }}{{ .RelPermalink }}

I’m not sure why you want to define a baseURL under the params key… it already exists under the language key.


Without access to your site I have no way of efficiently troubleshooting this.