I used to utilize GitHub Pages to serve static content for my blog. I secured it behind Cloudflare to employ a custom domain and automate HTTPS certificate management. Additionally, I utilized a few Page Rules to implement redirects:

  • From www.* to non-www,
  • From HTTP to HTTPS,
  • And for some SEO renaming.

Unfortunately, in the Free plan from Cloudflare, you are limited to:

  • 3 Page Rules (with simple glob matching),
  • 10 Transformation Rules (no regex rules),
  • 10 Redirect Rules (no regex).

I made use of a combination of these rules, but due to these limitations, I couldn’t meet all of my requirements. I have few hundreds of broken URLs reported by Google Web Console. Google still remembers that I migrated from Wordpress and attempts to index some paths I no longer host. Although I attempted to utilize Hugo’s aliases 1, it only facilitates 1-to-1 matching. I’m unable to address this issue within these constraints.

On the flip side, Cloudflare Page supports the _redirects file, which can host 2000 static and 100 dynamic redirects, totaling up to 2100 redirects 2. That’s more than what I need.

I decided to transition static file hosting to Cloudflare Pages3. There’s a helpful article describing the configurationexternal link , and the process is quite straightforward.

Now, what I needed was an easy way to generate this _redirects file.

Generating _redirects within Hugo

Basic syntax of _redirects files is simple 4:

[source] [destination] [code?]

I’d like to generate it automatically from Hugo’s aliases, then add few more. For that let create a new template file under layouts/_default/home._redirects with the following content:

Minimum layouts/_default/home._redirects content
{{- range .Site.Pages -}}
{{- if .Aliases -}}
    {{- $new := .RelPermalink -}}
    {{- range .Page.Aliases }}{{ . }} {{ $new }} 301
{{ end -}}
{{- end -}}
{{- end -}}

At the end of this file, you can add your own custom redirects. For me, these include taxonomy changes:

/tag/* /tags/:splat 301
/category/* /categories/:splat 301
/main/* / 301
/author/* /authors/:splat 301

Now, in the config.yaml or hugo.yaml, add the configuration to handle the new file type:

Extend Hugo's config with this
mediaTypes:
  text/redirects:

outputFormats:
  _redirects:
    name: _redirects
    mediaType: text/redirects
    baseName: _redirects
    isPlainText: true
    rel: alternate
    isHTML: false
    noUgly: true
    permalinkable: false

outputs:
  home:
    - HTML
    - RSS
    - JSON # I need it for the search
    - _redirects

That’s it. Deploy/rebuild your website at Cloudflare and check if redirects work as expected.

I must admit it’s not my original idea — I found it in the sourcesexternal link of russ.fooexternal link ’s blog. Check it out, there are more fancy modifications.


Enjoyed? Buy Me a Coffee at ko-fi.com