Apache borked my links!

My new site, product of just a few days, works perfectly with the hugo server. Switched back to Apache, and navigation is busted.

This is a simple blog site set up basically according to the Hugo howto [1]. Content structure is:


I added a couple of taxonomies, some templates etc., and a menu as documented here. This menu has urls “/apple” , “/banana”, “/currant”, “/about”, “/tags” and “/authors”.

That’s as the links are in the HTML. As seen in the brower, the domain name is prepended: “http://localhost:1313/apple”, etc…

So, I quit out of the Hugo server and fell back to apache. My web projects are in /srv/www with one subdirectory per site - so /srv/www/site1, etc…
And there’s an Apache VirtualHost for each site/project.

At first the browser was pointed to just /srv/www/hugo and didn’t find an index of course, Hugo puts the generated site in its /public, right? So I corrected that, and now the VH now looks like this:

<VirtualHost *:8087>
    #ServerName example.com
    #ServerAlias www.example.com
   ServerAdmin webmaster@localhost

    DocumentRoot /srv/www/hugo/public

    LogLevel info warn
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

(VH’s just like this work fine with other frameworks, some with rewrite rules, etc.)

Now the index page comes up OK, suppose I click the ‘apple’ link - this goes to an apache-generated list of contents under /apple (instead of the nicely templated page in the correct site). One of the listed files is index.html, but if I click on that, it’s interpreted as http://localhost:8087/index.html instead of http://localhost:8087/apple/index.html, and the client is back on the home page.

The block in apache config looks as so:

<Directory /srv/www/hugo>
    Options Indexes FollowSymLinks MultiViews
    AddDefaultCharset UTF-8
    AllowOverride All
    Require all granted

Those are basically defaults. How can I make Apache do whatever magic the Hugo server is doing to make the site work?

This would be easier to troubleshoot if we could see the files in your site. At the very least go into your content directory and use the tree command, and include the output. Also, what is in your config.toml?

For an example site I have, this is the output from tree content/:

└── post
    ├── example-book.md
    └── mary-poppins.md

If Apache is showing files instead of your index.html, it seems to be an apache settings problem.

I think you need a DirectoryIndex line in your config block:

     DirectoryIndex index.php index.html index.pl index.cgi
1 Like
george@box1:/srv/www/hugo$ tree content
├── about.md
├── authors
└── blog
    ├── testfile1.md
    └── testfile2.md

Names changed but it’s really only those files. My nav testing has been just following every link, feeding bogus to get 404, looking for right links, lists, layouts etc.

The config file:

archetypeDir = "archetypes"
baseURL = "http://example.org/"
buildDrafts = false
buildFuture = false
buildExpired = false
relativeURLs = false
canonifyURLs = false
config = "config.toml"
contentDir = "content"
dataDir = "data"
defaultExtension = "html"
defaultLayout = "post"
defaultContentLanguage = "en"
defaultContentLanguageInSubdir = false
disableKinds = ["RSS"]
disableLiveReload = false
disableRSS = true
disableSitemap = true
enableGitInfo = false
enableRobotsTXT = false
disable404 = false
disableHugoGeneratorInject = true
enableEmoji = false
enableMissingTranslationPlaceholders = false
footnoteAnchorPrefix = ""
footnoteReturnLinkContents = ""
googleAnalytics = ""
languageCode = "en-us"
layoutDir = "layouts"
log = false
logFile = ""
metaDataFormat = "toml"
newContentEditor = ""
noChmod = false
noTimes = false
paginate = 10
paginatePath = "page"
# permalinks:
pluralizeListTitles = true
preserveTaxonomyNames = false
publishDir = "public"
pygmentsCodeFencesGuessSyntax = false
pygmentsStyle = "monokai"
pygmentsUseClasses = false
rssLimit = 15
# sitemap =
source = ""
staticDir = "static"
stepAnalysis = false
themesDir = "themes"
title = "example.com"
uglyURLs = false
disablePathToLower = false
hasCJKLanguage = false
verbose = false
verboseLog = false
watch = true

 # category = "categories"
 tag = "tags"
 author = "authors"

 RecentLimit = 12

  plainIDAnchors = true
  extensions = ["hardLineBreak"]
  taskLists = false
  smartypants = false
  angledQuotes = false
  fractions = false
  smartDashes = false
  latexDashes = false
  hrefTargetBlank = false
  extensionsmask = []

It’s basically pasted from https://gohugo.io/overview/configuration/ , I modified items that seemed relevant and left the rest.

example.com” in baseUrl is literally that, a variation of the example in the doc. title, however has the real domain name because this makes it appear on pages, without requring it to agree with the actual domain, which in this environment can be localhost:8087 or

dir.conf, effective for all sites, has:

DirectoryIndex index.html index.php

What are the /apple, /banana, /currant from the original example? With the tree you posted, what are the paths you are trying to generate?

The links are currently “/blog” (the fictitious ‘apple’, index page listing articles), “/about” (a singular page with a different format, content is the about.md), “/tags” and “/authors” are taxonomy term pages with links to pages under “/blogs”; later there will be for example “/reference” (the fictitious ‘banana’) with .md pages under it, and a third directory of text-based pages (the fictitious ‘currant’).

(It’s minimal now, but once the structure is working, it will be simple to add more of each type (another index page with content pages under it; another special page like “about”…), by just cloning and changing template, adding md files etc…)


  • Tried turning off “Indexes” option in Apache config, then the home page still worked, but each directory (/authors, /blog, …) got 403 permission denied.
  • Set “relativeURLs = false” in Hugo config, cleared out /public and regenerated - no effect on anything

---- ( changed the “solved it!” here ) ---------------

It takes a combination of settings. Most combinations of these things produced no change or worse, so it was discouraging to go thru many cycles of modify, rebuild and check, but then got partial success and clues.


  1. In config.toml:

    • baseURL = "/"
    • relativeURLs = true
    • uglyURLs = false
  2. In Apache configuration:

    • <Directory> block in /etc/apach2/apache2.conf as shown above
    • DirectoryIndex index.html (can be in a dir.conf or in the <VirtualHost> block for the site; the latter is normally in a nameOfSite.conf)
    • DirectorySlash on (same locations)
  3. My link-generating template (navlinks.html, a “partial” that goes into navbars) now looks like this:

    <div class="nav">
    <a href="/about">about</a>

    {{ range $taxoname, $taxo := .Site.Taxonomies }}
    <div class="nav">
    <a href="/{{ $taxoname | urlize }}">{{ $taxoname }}</a>
    {{ end }}

    {{ $sections := where (.Site.Pages) "Kind" "section" }}
    {{ range $sections }}
    <div class="nav">
    <a href="{{ .Title | urlize }}">{{ .Title | lower }}</a>
    {{ end }}

Formerly I was inserting “/” at the left of each href for the “section” loop, but doing that only on the others gets the correct result for me.

Bonus, this also still works on the Hugo server as well.

Oops, sorry, not completely solved yet. Each index page appears correctly if you go to it from the home page, but some links become relative to where you are linking from.

Specifically it’s a problem when going from “about” to a section. From the home page I click “about”, and there’s the “about” page, but then clicking “tags” tries to go to the nonexistent /about/blog rather than to /blog.

Looking in the HTML reveals the “blog” link from that page in particular is lacking the initial slash, tho it’s clearly put on there in the template.

Meanwhile I now have `` and putting a slash at the left of every link created in navlinks.html and using baseURL = "" and relative links = false in Hugo config.

Narrowed down to one remaining problem. Now with relativeURLs = false and baseURL = "/" in Hugo config, it all works except linking to taxonomy terms page. For example, on /blog index page (a list page), linking to “tags” gets /blog/tags not /tags.

And that’s because in the HTML the url is only ‘tags’ instead of ‘/tags’. The template code that generates those links is:

{{ range $taxoname, $taxo := .Site.Taxonomies }}
<div class="nav">
    <a href="{{ .Site.BaseURL }}{{ $taxoname | urlize }}">{{ $taxoname }}</a>
{{ end }}

Keeping in mind that {{ .Site.BaseURL }} is “/”, that ought to put a slash as the first character of the url. Yet neither hte above, nor hardcoding “/” actually causes a link to appear. Somehow it’s getting stripped off or never put on. It’s not clear how a slash can be prepended if the templater won’t allow it to be hardcoded in the HTML.
(Is this a bug?)

If you figured it out, that’s cool, but I would personally be trying to figure out why the default Apache settings weren’t working. Having your baseURL set to / may not work out for ya in certain circumstances.

As for linking, check the menu docs, it has advice on generating URLs.