Using Apache2 asis module for redirects

In the course of a non-Hugo project I’ve been working on (I’m hoping to circle back here soon more regularly in the next couple of months), I found a convenient way to make aliases into 301 redirects when you have an Apache2 (2.4.x) server with mod_asis, which I thought I would share.

(This avoids enabling .htaccess files as, according to Apache, enabling them results in a performance hit).

Synopsis

  • Turn off built-in alias files (generates index.html with meta refresh)
  • Have Hugo generate a shell script that creates .asis files (that do ‘real’ (30x) redirects)
  • Run the script and remove it (since it will be in your public directory). This generates all the .asis files.
  • Configure your Apache2 server to use the asis module for your Hugo site.
  • Upload you site to the server.
  • Test … you should be seeing real redirects when you access an alias.

The Details

This builds on other tips from the forum (for generating a list of redirects), but I don’t have the link handy.

.htaccess, humans.txt with template logic - tips & tricks - HUGO

config.toml for your site

…
disableAliases = true
…

[outputs]
home = ["HTML",  "RSS", "redirectasis"]

[outputFormats]
[outputFormats.redirectasis]
basename = "mass-redirect.asis"
isPlainText = true
mediaType = "text/redirectasis"

[mediaTypes]
[mediaTypes."text/redirectasis"]
suffices = ["sh"]

Add a layouts/index.redirectasis.sh template

#!/bin/bash

{{ range .Site.Pages -}}
	{{- $curPage := . -}}
	{{- if .Page.Aliases -}}
		{{- $new := .Permalink -}}
		{{- range .Page.Aliases -}}
			{{- if eq $new (printf "%s%s" (strings.TrimSuffix "/" $curPage.Site.BaseURL) .) -}}
				{{- errorf (printf "'%s' has a circular alias" $new) -}}
			{{- end }}
if [ ! -s "{{ strings.TrimSuffix "/" . }}/index.html" ]; then
mkdir -p ."{{ strings.TrimSuffix "/" . }}"
cat >"./{{ strings.TrimSuffix "/" . | strings.TrimPrefix "/" }}/index.asis" <<EOF
Status: 301 Moved Permanently
Location: {{ $new }}

EOF
fi
		{{- end -}}
	{{- end -}}
{{- end }}

Build the site (and script) and execute the script

hugo
cd public
bash mass-redirect.asis.sh
rm mass-redirect.asis.sh

Configure Apache2 to use the asis module

  1. Enable the module. For Debian/Ubuntu this is simply sudo a2enmod asis on a server with Apache2 installed.
  2. Configure files ending in .asis to use the asis handler
    1. Add the following in the context where you want it (e.g. server-wide, vhost, <Directory> block)

      <IfModule mod_asis.c>
          <IfModule mod_mime.c>
              AddHandler send-as-is asis
          </IfModule>
      </IfModule>
      
  3. Restart Apache2

Final steps

  • Upload your site
  • Browse (or curl or wget, or …) to one of your aliases.
    • For example, if you have aliased post/my-original-project-page to projects/my-current-project-page/, browse to https://example.com/post/my-original-project-page and you should be redirected to https://example.com/projects/my-current-project-page/ with a 301 redirect.

Conclusion

I hope some folks find this useful, and I’ll try to answer any questions.

I also have a question for @jmooring (and bep, but I don’t want to tag him):
It would really handy if overriding the aliases template could include generating files with an .asis extension instead of .html. Looking at the docs, and the source code, it doesn’t look like this was possible a few months ago. Has that changed, and if not, could it?

3 Likes