HTTP2 preload directive for fingerprinted asset in .htaccess

I want to put an .htaccess file in my asset pipeline so I can put HTTP2 preload directives in there for server push.

Basically, I need my fingerprinted asset variables {{…main.css | fingerprint… }} to resolve inside the .htaccess file otherwise I have to manually set them each time the asset is changed.

I just started with Hugo last month but, from the looks of it, this looks like something the asset pipeline was not designed for.


You could place your .htaccess in the static folder and it’ll be copied to your site root.

Explain more what you’re trying to do here. An example would be helpful.

In my .htaccess, I want an HTTP2 server push preload directive, i.e.,

<FilesMatch “index.html”>
Header set Link “<main.min.jdfsuf90jsfkasf90839kfsdfi0sif.css>; rel=preload; as=style”
< / FilesMatch>

When the fingerprinted asset is changed in my asset pipeline, I want its fingerprinted name to be updated in my .htaccess file. For this, I need to be able to specify a {{ }} inside my .htaccess file. I tried 2-3 hacks to get Hugo to do this for me, including putting the .htaccess in my assets folder and calling resources.* on it, but was unsuccessful.

Is this possible? If not, I will have to resort to an external script.

I see. Yeah this is not possible, as far as I know. You’ll have to reset to external script as you mentioned.

Thanks for the quick replies.

After some more hack-hackiness, I figured out that my original method of calling resources.* works, specifically resources.ExecuteAsTemplate. I had just messed up the syntax a bit on my first attempts and assumed Hugo couldn’t do it.

For anyone else who wants to do this:

  1. Put .htaccess in assets folder
  2. Call resources.ExecuteAsTemplate on the .htaccess file (from anywhere)
  3. Call .RelPermalink on that resource (from anywhere) so Hugo actually puts it into public. I do this in an HTML comments tag < !-- – >, which I strip out with minify, i.e., it never shows up in source.

Still in the design stage. First time building a site in years, so I am following HTTP2/HTML5 best practices from the get-go. So glad I happened upon Hugo!

From all I’ve read (including performance analyses for mobile/desktop):

  1. Pushing only critical CSS will definitely improve speed, rendering faster (generally) than inlining that same CSS.
  2. For other critical things, you need to measure to see how/if push helps. For example, if you push everything or even too many things, render becomes slower (generally) not faster.

This is where the “nopush” directive for preload comes in. Critical assets will definitely benefit from declaring them in the header, even if you don’t push them. The browser will request them (and likely get them) faster. At the very least, everyone should be doing this even if they are not performance nuts like me!

1 Like

I have the same issue.
Would you mind detail your solution as I am not a coder and not very familiar with the syntax ?
A detailed coding example would be very helpful.
Thanks in advance

I’ll clarify further:

  1. Put your .htaccess file in the top-level “assets” folder (Hugo doesn’t create the “assets” folder by default, so create it if it’s not there).
  2. In index.html (or any .html file), call resources.ExecuteAsTemplate on the .htaccess file like so:

{{ $h := “.htaccess” }}
{{ $h2 := resources.Get $h | resources.ExecuteAsTemplate $h . }}

  1. Call .RelPermalink on that resource so Hugo actually puts it into public. If you do this in an HTML comments tag < !-- – > and later strip it out with minify (use the --minify flag on build, i.e., “hugo --minify”) so it doesn’t show up in source. You can do this lik so:

< !-- {{- $h2.RelPermalink -}} --> (This is a regular HTML comment tag, but the forum isn’t letting me post it correctly. Remove the space between the first < and ! to make it work…)