Multilingual and Static Files Duplication

I don’t remember exactly when I first met Hugo to say for sure it didn’t have multilingual support or if what was available was as it is today. But, be it because of limitations at that time or lack of knowledge of my part for “more complex features”, back then I ended up translating a fan-site by “brute-force”

All translatable files always had the language suffix between the filename and the extensions (i.e. about.en.md) but everything else, like listing all available translations, the relationship between Pages and even the Language Switcher, had been created by hand.

Now, after migrating a lot of data from FrontMatter Parameters to Data Files, already in the much more efficient subdirectories format (i.e. /data/en/file.json), I decided to revisit the i18n/l10n as well and with a few changes in my config.yaml (see below), almost everything was up and running smoothly (I’m still figuring out how to deal with URLs…).

However, after compiling, I noticed that everything under /static was getting duplicated for each language available and that’s most undesirable for me because there are several pictures under /static/assets/images used regardless the language chosen, summing something around 80 MB — and that’s already super optimized.

This is the meaningful part of the new config.yaml:

languages:
  en:
    languageName: English
    baseURL: https://www.site.com/
    contentDir: content/en
    weight: 1
  pt:
    languageName: Português
    baseURL: https://pt.site.com/
    contentDir: content/pt
    weight: 2
  es:
    languageName: Español
    baseURL: https://es.site.com/
    contentDir: content/es
    weight: 3

And this the static folder directory:

|-\ static
  |-\ assets
    |-\ fonts
    |-\ images
    |-\ js
    |-\ css
  |-\ en
  |-\ pt
  |-\ es

js and css don’t actually exist. They’re added in there when resources are compiled and minified

After compiling, I’m receiving as output this structure:

|-\ public
  |-\ en
    |-\ assets
  |-\ pt
    |-\ assets
  |-\ es
    |-\ assets

While I would need something like:

|-\ public
  |-\ en
  |-\ pt
  |-\ es
  |-\ assets

I would prefer all subfolders within /static to remain under /assets, this way I can Cache-Control them all with a single rule in CloudFlare and etc.

I’ve found this issue relating a case pretty much like what I’m experiencing. But as you can see there’s no global staticDir nor a per-language staticDir2 defined.

I am not seeing this behavior when I test what you describe locally.

I tested with the HugoBasicExample and a random theme. I made sure to delete disableLanguages = ["fr"] from the config.

Then under /static/ I replicated the structure you described more or less i.e.

|-\ static
  |-\ assets
  |-\ en
  |-\ fr

When I execute hugo I am getting the exact same directory structure under /public/

Something else is at work here and I think that you need to share your project because we need to see the full context.

1 Like

I tested this repository you shared, changing only the directory structure to match with the contentDir directive added in the config.toml to match my own and by using it with this bare minimum theme I’ve got what I was expecting too.

But when I cloned this theme in my project (changing the theme directive, of course), it didn’t work and the assets directory was getting duplicated once again for each language available.

Then I tried to isolate the problem, digging out for problems outside my theme, deleting everything “superfluous”, from directories only my theme uses to specific FrontMatter Parameters I have and it still didn’t work.

I proceeded to remove more and more information (Data Files, i18n, Custom URLs…) until I had nothing but the Title and, in some pages, some minimal content. And it still didn’t work!

Because now it’s pretty much a brand new site, without any of my personal stuff, I can share it publicly, but if you don’t mind I’ll just zip it and share in my Dropbox 'cause it’s more unlikely that I would delete it later so, perhaps, this helps someone else in the future.

Thank you for your time

I don’t have the time to troubleshoot this in depth. Maybe someone else will.

But I had a look at your pretty extensive config.yaml over here and it seems that you have configured different static directories per language, so of course you are getting the behavior you reported. Eliminate the multiple static directories that are currently configured per language and you will not have static files duplicated when the project is published.

No, these directives are commented. I would remove them but I thought leaving them there as a reference of different approaches would be good for debugging.

Right. Of course they are. Sorry I missed the hash. I’m kind of busy today.

Don’t worry, it’s gonna be such a big change that I left it in a separate branch to not affect my publishing.

I’ll keep waiting for you or anyone else to jump in

While I was waiting for someone who could shed some light to this problem, I decided to use the one thing this new repository I’ve built to isolate the problem wasn’t using if compared to the one onedrawingperday provided: a TOML config file instead of a YAML.

Doesn’t make sense but it wouldn’t hurt trying, so:

config.yaml

---
baseURL: 'https://www.site.com/'
defaultContentLanguage: en
LanguageCode: en-US
title: Multilingual Test Site
theme: hugo-bare-min-theme
googleAnalytics: UA-82997629-1
MetaDataFormat: yaml
enableRobotsTXT: false
EnableGitInfo: true
pluralizelisttitles: false
removePathAccents: true
#disableFastRender: true
#paginate: 5
preserveTaxonomyNames: true
disableHugoGeneratorInject: true
disableKinds:
  - '404'
  - sitemap
publishDir: ../multilingual-test-site
params:
  development: false
  debug: false
  author: Next WDDS
  since: "2017-07-15 13:13:26"
  facebook:
    appID: '1442765462474120'
    page: 'https://www.facebook.com/SomeFacebookPage'
  twitter:
    page: 'https://www.twitter.com/SomeTwitterProfile'
  adsense: 'ca-pub-XXX'
  iso:
    en: en_US
    pt: pt_BR
#permalinks:
#  en: '/en/:section/:slug/'
#  pt: '/pt/:section/:slug/'
#staticDir: ./static
languages:
  en:
    languageName: English
    baseURL: https://www.site.com/en/
    contentDir: content/en
    #staticDir2: ./static/en
    weight: 1
  pt:
    languageName: Português
    baseURL: https://www.site.com/pt/
    contentDir: content/pt
    #staticDir2: ./static/pt
    weight: 2
---

config.toml

baseurl = "https://gohugo.io/"
title = "Multilingual Test Site"
author = "Steve Francia"
copyright = "Copyright © 2008–2018, Steve Francia and the Hugo Authors; all rights reserved."
theme = "hugo-bare-min-theme"
canonifyurls = true
paginate = 3
languageCode = "en"
DefaultContentLanguage = "en"
defaultContentLanguageInSubdir = true
#disableLanguages = ["pt"]
publishDir = "../multilingual-test-site"
MetaDataFormat = "yaml"

[languages.en]
languageName = "English"
weight = 1
title = "Multilingual Test Site"
contentDir = "content/en"

[languages.pt]
languageName = "Português"
weight = 2
title = "Site de Teste Multilíngüe"
contentDir = "content/pt"

There’re several differences, of course, as my original YAML have a few additional configurations but, generally speaking, they’re pretty much the same. I even converted from YAML to TOML and vice-versa to triple-check.

Then I spotted the difference: The baseURL directive under each of the language definitions, each one pointing to https://www.site.com/<LANG_CODE>. Once I commented out these lines, everything worked as expected, with the assets folder outside the /en and /pt

But remains the question, why?

Why configure baseURL per language? I’m just asking. I thought Hugo takes care of this for you in multilingual. (Also note that I’ve never needed to use multilingual myself).

I would be lying if I told you I was 100% about that option. I initially thought about using subdomains and as much as I could understand the docs I should add this option (remember, prior to this everything was done by “brute force”).

Of course, from the very beginning, my brain simply blocked the fact I was passing a folder instead of a subdomain to them (and probably that was the root of the problem).

Am I more or less on the right line of thought here or what?

I think that you are right. So basically you don’t need to pass a different baseURL per language since each one is published in a subdirectory and not a subdomain.

1 Like