Adding an RSS feed

RSS capabilities of Hugo

📅 22 Jan 2021

An RSS feed for the Hugo-generated site.

In my tutorial on how to set up a Hugo site based on Simple.css, I skipped the part about adding an RSS feed. In this post I want to explain how this can be added.

In fact, what I failed to realize while writing the tutorial is that Hugo will automatically create RSS feeds out-of-the-box, even without explicit configuration. So we’re in pretty good shape already.

However, this default feed might not exactly correspond to what we want to achieve. E.g. Hugo will create separate feeds for each directory, and will also include the “about” and “contacts” pages.

Next to that we also want to put a reference to the RSS feed in the <head> of our site’s pages.

Tweaking the default RSS feed

Our goal is to set up only one RSS feed in the root folder of the website which will only show blog posts.

Let’s first switch off RSS feeds for all subfolders, which will only leave the feed in the root folder. This can be achieved by adding the following to the config.toml file:

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

Now we want it to only show the blog posts. Unfortunately, this can only be done by making a copy of the default Hugo RSS template and editing it.

We’ll start by saving a copy of the original default Hugo RSS template to layouts/rss.xml of our website. Then we’ll replace the code on line 28

    {{ range $pages }}

which will loop over all pages of our site, by the following piece of code

    {{ range where .Site.RegularPages "Section" "blog" }}

which will only grab the blog posts.

The resulting file layouts/rss.xml should then look like this:

{{- $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">
  <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 where .Site.RegularPages "Section" "blog" }}
    <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>{{ .Summary | html }}</description>
    </item>
    {{ end }}
  </channel>
</rss>

Next step is to add a link to the feed in the head of each page, such that RSS clients can automatically find the feed.

This can be achieved by adding the following to our head partial file layouts/partials/head:

    {{ with .OutputFormats.Get "rss" -}}
        {{ printf `<link rel="%s" type="%s" href="%s" title="%s">` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
    {{ end -}}

The resulting file will then contain the following:

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="icon" href="/images/favicon.png" />
    <title>{{ .Title }} | {{ .Site.Title }}</title>
    <meta name="description" content="{{ .Description }}" />
    {{ with .OutputFormats.Get "rss" -}}
        {{ printf `<link rel="%s" type="%s" href="%s" title="%s">` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
    {{ end -}}
    <link rel="stylesheet" href="/css/simple.min.css"/>
</head>

Tweaking the name of the RSS feed file

By default the RSS feed file is called index.xml. In case you want to change the name of that file (e.g. to rss.xml), you can add the following to the site’s config.toml file.

[outputFormats]
  [outputFormats.RSS]
    mediatype = "application/rss"
    baseName = "rss"

Reference

Most of the RSS feed setup in this post is based on information found in another blog.

You can also find all the files related to these tutorial in a dedicated Github repository.



💬 Looking for comments?

I don't have comments on this site as they're difficult to manage and take up too much time. I'd rather concentrate on producing content than managing comments.

Instead of leaving a comment, feel free to contact me ✉️ contact me instead.