One thing I’ve unfortunately neglected for a little while now on my blog was the RSS feed - mostly because I didn’t have a clue how to make Hugo do it as I’d like. There was a couple of issues:

  • Only the summaries of my posts were fed via RSS - not the full contents. I do not do any sort of content tracking on my site because I don’t want to foist vaporware like Google Analytics on my readers, so it really doesn’t matter to me whether people read my content from the RSS feed or from the main site - that they read it is enough!
  • The links from the RSS feed were broken.
  • I didn’t have an explicit link to signify that my site even supported RSS on the main page.

Let’s look at these in-order.

Full Contents Please!

So I wanted full content rather than summaries of my posts on the RSS feed. Luckily Hugo provides a way to intercept and replace the default RSS template with your own custom one. I followed this guide to try and get it working - but in my RSS reader of choice while the full contents were now being included in the final RSS feed, the HTML tags were being displayed wrongly. I scratched my head for a long while over this before I realised that with RSS 2.0 there are two ways to encode HTML data within an RSS description - and my reader only liked the CDATA approach.

What I ended up with was the following:

<!--https://www.godo.dev/tutorials/hugo-full-text-rss/-->
<!--https://raw.githubusercontent.com/gohugoio/hugo/master/tpl/tplimpl/embedded/templates/_default/rss.xml-->

{{- $pctx := . -}}
{{- if .IsHome -}}{{ $pctx = .Site }}{{- end -}}
{{- $pages := slice -}}
{{- if or $.IsHome $.IsSection -}}
{{- $pages = $pctx.RegularPages -}}
{{- else -}}
{{- $pages = $pctx.Pages -}}
{{- end -}}
{{- $limit := .Site.Config.Services.RSS.Limit -}}
{{- if ge $limit 1 -}}
{{- $pages = $pages | first $limit -}}
{{- end -}}
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>{{ if eq  .Title  .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}{{ end }}</title>
    <link>{{ .Permalink }}</link>
    <description>Recent content {{ if ne  .Title  .Site.Title }}{{ with .Title }}in {{.}} {{ end }}{{ end }}on {{ .Site.Title }}</description>
    <generator>Hugo -- gohugo.io</generator>{{ with .Site.LanguageCode }}
    <language>{{.}}</language>{{end}}{{ with .Site.Author.email }}
    <managingEditor>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</managingEditor>{{end}}{{ with .Site.Author.email }}
    <webMaster>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</webMaster>{{end}}{{ with .Site.Copyright }}
    <copyright>{{.}}</copyright>{{end}}{{ if not .Date.IsZero }}
    <lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
    {{ with .OutputFormats.Get "RSS" }}
      {{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
    {{ end }}
    {{ range $pages }}
    <item>
      <title>{{ .Title }}</title>
      <link>{{ .Permalink }}</link>
      <pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
      {{ with .Site.Author.email }}<author>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</author>{{end}}
      <guid>{{ .Permalink }}</guid>
      <description>{{ safeHTML "<![CDATA[" }}{{- .Content | safeHTML -}}{{ safeHTML "]]>" }}</description>
    </item>
    {{ end }}
  </channel>
</rss>

With the only thing I changed was the line:

<description>{{ safeHTML "<![CDATA[" }}{{- .Content | safeHTML -}}{{ safeHTML "]]>" }}</description>

What this does is dump the original HTML content as is (that’s what the safeHTML command does) and wrap it in the <![CDATA[ and ]]> tags. This meant that my content was being displayed correctly.

I then just had to place the above in <root>/layouts/_default/rss.xml et voila, it worked!

All my links in the RSS were broken - the links to my main site and also the links to image content on my main blog. I don’t quite know how I forgot to do this (or how my site actually worked for as long as it did), but I had forgotten to specify the baseurl in the config.toml. Just pointing this at my site fixed the issue.

Advertising RSS Support

Although my site always (poorly) supported RSS, I never advertised it. To solve this I’ve just added an RSS badge to the footer of the page to help people find the feed that want it. Nothing fancy, just an image and a link.

Wrapping It All Up

Now I have fully working RSS - and thanks to a very helpful push from an avid reader (thanks Augustin!) I’ve also enabled SSL/https on my site - and made it the primary way to view my content. My hosting provider Gandi has offered simple SSL integration for a while now, but I had to upgrade my small instance to small+SSL, and I just hadn’t gotten round to it. But no more - I now serve secure content by default!

Sorry for any RSS fans that’ve been maligned for a while now, but hopefully this post will get my RSS subscriptions to rise now that my content is displayed in all its glory.

You can find the RSS feed at this link https://www.neilhenning.dev/index.xml.

Tioraidh a chàirdean!