Full-text RSS in Hugo

I tried, I swear I tried. I really didn’t want to be the kind of person that puts together a blog using a static site generator and writes the 187.435th article on the internet title “How I use tool X to write my blog”. This one is for a good cause, though.

Why full-text entries?

RSS has two perennial debates. The first is about how dead or kinda dead it is. The other is of a much more practical matter: should we provide the full-text of any posted content or just a teaser entry to get your readers into your site? In other words, do you want people to read and enjoy your writing and use whatever tools fits them or do you worship the cult of Satan and sold the last scraps of your soul for a meager number of clicks?

It is not really a debate. Full-text feeds make the web more robust and decentralized, it gives power to the users (no wonder the big media companies would love to see it really-really-dead) and it can arguably help content producers to disseminate and reach larger audiences. Full-text feeds should be the standard in any publishing platform so that perhaps we wouldn’t need to have tools, libraries, and websites that convert RSS partial-text into full-text feeds.

So, it is easy to imagine how disappointing it was when I realized the default RSS feed generated by Hugo provides only the summary of each page on its description.

Fear not, there is an easy solution for that.

Overriding the RSS template

As of today, the Hugo template code that generates the RSS feed page is as follows:

{{- $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 -}}
{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <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 }}
      <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>{{ .Summary | html }}</description>
    {{ end }}

The .Summary attribute is - you guessed it - only a summary of your hugo posts. It can be defined by the author and by default it is simply the first paragraph of your post.

If the theme you are using has already customized their RSS feed (perhaps due to multi-author or multi-language support), chances are that it already has defined a different template, and most likely to be located at <path_to_theme>/layouts/rss.xml. If it hasn’t been customized, you will can then create a new file on <path_to_theme>/layouts/rss.xml with the exact content above to give you a way to edit it.

In either case, the one thing you will have to do with the template you have is to find any reference to .Summary and replace it with .Content. Done.

Is that it?

Well, if all you want is to write and have a full-text feed, yes! Of course there are plenty of interesting things that could also be done with RSS. A quick look at the RSS2 Specification might give you more ideas. Perhaps turn your Hugo site into a podcast platform?