How to force index.html in all <a>?


Let me try to explain.

Hugo tends to make “human” URLs. That is, a URL that does not request the index.html document.

This is incompatible with the way that I am hosting a hugo site on Amazon’s S3 w/ Cloudfront CDN on top.

Ultimately, i need to know if there’s a way to add / force ugly urls for all links.

<a href=""></a>

needs to become

<a href=""></a>

Is there something that i can do / am missing in the site config that will make this easy

Here’s a bit of background:

Hugo has a uglyURLs setting, but it is less ugly than your scheme.

But I think you are wrong. We serve the Hugo docs via Cloudfront:

And if you were happen to be right, you should really shout out loud to Amazon, not us.

Thanks for the reply.

Yes, i looked into the uglyURL setting right away… but as you’ve been able to guess, it’s not “ugly” enough for the way that AWS CF and S3 play together.

I will open a support ticket w/ amazon asking for the ‘index.html’ behavior to be the same regardless or which S3 endpoint is used to access the content.

Hi bep. I am working with AWS support on this currently. You’re right that an ‘implied index.html’ works fine with CloudFront when the distribution is configured to sit in front of an S3 static website endpoint. In that mode, S3 is acting as a webserver which can do this. But switch to using a OAI directly, as documented at, and a hugo-generated site breaks hard.

Here’s a AWS blog post showing a lambda hack to get around this issue:

I would very much prefer not to use compute to simply rewrite requests to specify index.html.

Any other users out there know how to get around this? Perhaps there’s a config I’m doing wrong on AWS? If yes I would hope/assume the AWS CloudFront guy I’m working with would know about it; I’m suspecting not.

Regardless, it would be just fantastic if Hugo had a rendering option whereby the full URL including index.html were always emitted, and we never had to rely on this website feature of serving an implied url.

Is this possible in Hugo, while still rendering relative URLs?

Any other suggestions from the field?



Rather than use {{ .RelPermalink }} or {{ .Permalink }}, you could use {{ .File.Path }}. However, I would want to find another way rather than using a workaround just because of your hosting provider. I suppose you could use {{ .Render "url" }} or something like that to alternate between the two if you decide to change it later.

IMO, the ideal option would be a config setting which would enabling rendering behavior which would explicitly link to */index.html rather than just to the containing directory.

I believe the Lambda Edge option for URL rewriting will be able to be a workaround for now. But it sure does feel like a kludge. …I’d be very happy if there’s some config feature in CloudFront which doesn’t require explicit URLs in all cases, but so far, we haven’t found it.



Confirming for others here that according to AWS Support, AWS CloudFront using an Origin Access Identity is not compatible with websites where index.html is implicit

I will be switching to their recommended approach using a S3 webserver. Instructions for restricting S3 web server access to only this custom origin are here: