Help with re-used content in multi-lingual site


We are currently using Hugo’s multi-lingual features to support branded “variants” of the same core content that we manage for several customers. Our content structure makes heavy use of symbolic links, which has forced us to stay at Hugo 0.43 as symbolic link support was largely dropped after that. We’d like to be able to move forward with upgrading Hugo, but I am unsure of the best approach. Our current structure looks as follows:

  site2/ (symlink to site1)
  site3/ (symlink to site1)
  site5/ (symlink to site4)
    foo/ (symlink to site6/foo)
    bar/ (custom bar/ content)

Since most of the content is the same between the sites, this approach worked well for us. My initial thought was to try to make use of Hugo modules, but it’s unclear to me in my reading if that would work any differently (would we still ultimately fail because of symlink issues)?

I would just make separate content_xxx directories, but because some of the inner folders get symlink-ed as well, that doesn’t really solve anything.

Any ideas?

At the very least, make sure that you don’t have two different symlinks pointing to the same thing, as in my experience it causes a rather erratic behavior.

Symlink in themes was dropped at some point. In the project itself, the symlink support is (should be) better than before across the different folders.

That said.

What I would probably do is to mount your shared content into each site. Note that the file mounts in Hugo takes an optional lang attribute.

1 Like

Thank you for that clarification about symlinks in themes being the issue.

The shared content mounting via modules is exactly what I was thinking and I hadn’t seen a lang attribute documented. That’s precisely what I was looking for! Thanks.

Hi again @bep,

I took your advice and started to migrate some of the content over to modules, but I am running into a mental block on Hugo’s virtual filesystem and module mounts.

My approach so far was to create a module that is the base or shared content and then attempt to mount on top of that the content that is different for one of the languages. However, no matter what I try, I can’t get the “override” to happen. It seems that if the base content directory is mounted, nothing else can be mounted at any overlapped paths.

I added details to Issue with overlapping file mounts · Issue #7123 · gohugoio/hugo · GitHub, but I will replicate them here for clarity:

An example is the following content directory:


I then mount the content directory via a module:

  source = "base/content"
  target = "content"
  lang = "site1"

Then I try to override an image or markdown file with one from my language-specific module, which I would expect to just need:

  path = ""
  disable = false
  source = "content/support"
  target = "content/support"
  lang = "site1"

but that doesn’t work. I’ve tried every variation I can think of to make it more specific, thinking maybe the union file path reconciliation gives precedent to most-specific, but none of these made a difference:

  source = "content/support/images"
  target = "content/support/images"
  lang = "site1"
  source = "content/support/images/banana.png"
  target = "content/support/images"
  lang = "site1"
  source = "content/support/images/banana.png"
  target = "content/support/images/banana.png"
  lang = "site1"

Hi this thread is about an IMHO related problem and has some different suggestions that might be applicable to your case.

I appreciate the info, but I’m not sure the other thread is related at all. I want the fallback content, but ONLY if I don’t provide translated content, which is what I’m describing above.

Maybe I’m misunderstanding the purported relationship between my issue and the linked issue?

If I understand correctly, you want to have different sites (languages) that show the content of the default site (language) unless there is a localized version of the content in that site, and you are trying to achieve this with module imports. In the linked thread, people are trying to show content from the default language unless a localized version is available, but they are using other methods (not module imports) - I thought it’s related to the goal you want to achieve, not to the specific problem with the imports (I might have been wrong though, I don’t have much experience with multilanguage sites in Hugo).

Understood. Everything works as expected when modules aren’t being used. The root of this latest question was trying to implement the solution @bep suggested (content reuse via modules)