Featured image of post Optimize Hugo Website RSS Feeds: A Concise Guide

Optimize Hugo Website RSS Feeds: A Concise Guide

Learn to customize and enhance RSS feeds on your Hugo site. Control content, manage elements, and boost SEO impact with ease.


RSS (for Really Simple Syndication) is a web feed based on XML that allows users to be notified on access to updates on a subscribed online resource like a website. In the case of a blog, it allows people to subscribe to it to receive updates when a new article is published.

I will detail here how to propose RSS to the visitors of a Hugo website and how to customize it to fit your needs.


❯  How to enable RSS on Hugo?

It is enabled by default, so you have nothing to do πŸ˜‡. Running the command hugo builds your website and generates plenty of files and folders in your public folder located at the root of your project. Among the generated files is a file named index.xml. This is an XML representation of the website in the form of an RSS feed. This file will be notably used by RSS feed readers to subscribe to updates on the website (like a newly published post).


❯  How to exclude data from the RSS?

First, have a look at the index.xml of your website. You should see a list of item blocks, with the following format:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
...
<item>
    <title>title of a page</title>
    <link>its link</link>
    <pubDate>its publication date</pubDate>
    <author>its author</author>
    <guid>actually, same than link</guid>
    <description>a description</description>
</item>
        ...

If there is a item that refers to a page that you want to exclude from your rss feed, add this to its frontmatter:

1
2
3
4
5
+++
...
hidden = true
...
+++

Launch the build, and then the server commands will validate that the targeted page is no longer present.


❯  Control which RSS files are created

Cf the documentation relative to the RSS, several files are created by default:

  • for the home (at the root of the public folder);
  • for the sections (for example, at the root of the public/post and public/page);
  • for the taxonomies (at the root of the tags and categories);
  • for the terms (for every tag and every category).

If I take the same example I took in the section How to exclude URLs from the sitemap of the post Enhancing Your Hugo Sitemap: A Practical Guide:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
my-site/
β”œβ”€β”€ archetypes/
β”œβ”€β”€ assets/
β”œβ”€β”€ content/
β”‚   β”œβ”€β”€ categories/
β”‚   β”‚   β”œβ”€β”€ category1
β”‚   β”‚   β”œβ”€β”€ category2
β”‚   β”‚   └── ...
β”‚   β”œβ”€β”€ pages/
β”‚   β”‚   β”œβ”€β”€ page1
β”‚   β”‚   β”œβ”€β”€ page2
β”‚   β”‚   └── ...
β”‚   └── posts/
β”‚   β”‚   β”œβ”€β”€ post1
β”‚   β”‚   β”œβ”€β”€ post2
β”‚   β”‚   └── ...
β”œβ”€β”€ layouts/
β”œβ”€β”€ static/
β”œβ”€β”€ themes/
β”œβ”€β”€ hugo.toml
└── ...

The default configuration will add some index.xml files in your project as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
my-site/
β”œβ”€β”€ public/
β”‚   β”œβ”€β”€ categories/
β”‚   β”‚   β”œβ”€β”€ category1
β”‚   β”‚   β”‚   └── index.xml # if terms contains 'rss'
β”‚   β”‚   β”‚   └── ...
β”‚   β”‚   β”œβ”€β”€ category2
β”‚   β”‚   β”‚   └── index.xml # if terms contains 'rss'
β”‚   β”‚   β”‚   └── ...
β”‚   β”‚   β”œβ”€β”€ index.xml # if taxonomy contains 'rss'
β”‚   β”‚   └── ...
β”‚   β”œβ”€β”€ page/
β”‚   β”‚   β”œβ”€β”€ index.xml # if section contains 'rss'
β”‚   β”‚   └── ...
β”‚   β”œβ”€β”€ post/
β”‚   β”‚   β”œβ”€β”€ index.xml # if section contains 'rss'
β”‚   β”‚   └── ...
β”‚   β”œβ”€β”€ tags/
β”‚   β”‚   β”œβ”€β”€ tag1/
β”‚   β”‚   β”‚   β”œβ”€β”€ index.xml # if terms contains 'rss'
β”‚   β”‚   β”‚   └── ...
β”‚   β”‚   β”œβ”€β”€ tag2/
β”‚   β”‚   β”‚   β”œβ”€β”€ index.xml # if terms contains 'rss'
β”‚   β”‚   β”‚   └── ...
β”‚   β”‚   β”œβ”€β”€ tag3/
β”‚   β”‚   β”‚   β”œβ”€β”€ index.xml # if terms contains 'rss'
β”‚   β”‚   β”‚   └── ...
β”‚   β”‚   β”œβ”€β”€ tag4/
β”‚   β”‚   β”‚   β”œβ”€β”€ index.xml # if terms contains 'rss'
β”‚   β”‚   β”‚   └── ...
β”‚   β”‚   β”œβ”€β”€ index.xml # if taxonomy contains 'rss'
β”‚   β”‚   └── ...
β”‚   β”œβ”€β”€ index.xml # if home contains 'rss'
β”‚   └── ...
└── ...

Then, we remark that by default, plenty of files are generated. For the sake of simplicity of my blog, I only need the index.xml file at the root of the public folder. You can control files generated thanks by adding the following configuration:

1
2
3
4
5
[outputs]
home = ['html', 'rss']
section = ['html']
taxonomy = ['html']
term = ['html']

‘html’ controls whether HTML files are generated for the corresponding section, and ‘rss’ controls the creation of the RSS files. The configuration above indicates to Hugo that it has to create only one RSS file at the root of the public folder.

If you want to disable RSS on your website, you simply need to add the following configuration:

1
disableKinds = ['rss']

❯  Define the number of elements displayed on the RSS

By having a look on the [template defined on the gohugo project](this template), we can find a notion of limit.

40
41
42
43
44
...
{{- $limit := .Site.Config.Services.RSS.Limit }}
{{- if ge $limit 1 }}
{{- $pages = $pages | first $limit }}
...

It controls the number of elements displayed on the RSS feed. By default, when not set, all the pages of your website are present in the index.xml. Add this to your config.toml if you want to limit it to the n last elements:

1
2
[services.RSS]
limit = n

With n a number > 0.

Then, run the build and launch the server to verify that the index.xml has correctly been updated in taking this configuration into account.


❯  how to change the name of the rss file?

As I have said above, the RSS files are named file.xml. It is possible to change this behavior and choose a new filename. This can be achieved with the following configuration source

1
2
3
[outputFormats.RSS]
mediatype = "application/rss"
baseName = "filename"

with "filename" = the name of the file (without the extension .xml) you choose instead of index.

This is particularly relevant for RSS feed reader applications like Feedly. By default, it will keep the history of every entry present in this RSS ( cf this discussion on Reddit). So, if you have added in the past posts that you have deleted afterward, they are still visible on Feedly. You can then change the file’s name to “reset” the list of items.

If you are in the same situation, remember that making this change will break the ongoing subscriptions. Subscribers must then subscribe to the new file path to receive the notifications. As a result, do this when you do not have too many subscribers.


❯  control fields that are in the rss xml feed file

First, create a file named rss.xml in layouts/ and paste the content of the rss.xml file from gohugo.

Then updates it to match your need. Have a look on the documentation on w3schools.com to check the fields available.


❯  Description

By default, Hugo adds a section <description>...</description> in the XML that contains the 70 first words of the page. You can change this behavior in different manners.


❯  Add the integrity of the page

In the case where you want that people who subscribed to your RSS feed are able to see the full content of the page directly from their RSS application, you have to change the default behavior and add the full content in the description. To do so, you have to replace the line corresponding to the description with the following:

1
2
{{- $content := safeHTML (.Content | html) -}}
<description>{{ $content }}</description>

You can also replace .Content if you want something different that fits your needs. In my case, for instance, I replaced it with .Params.Description to display on the RSS feed the same description that the one displayed on the homepage and also on the top of my articles! 🀩


❯  Add the cover of the page

In the case where you add an illustration to your pages like a cover, you may also add them to have this image displayed in the RSS viewer app of your subscribers. Suppose that all your pages have a cover named “cover.jpg”. You can achieve this by replacing the description block with the following one:

1
2
3
4
<description>
    {{ "<" | html }}img src="{{ .Permalink }}/cover.jpg" alt="Featured image of post {{ .Title }}" {{ "/>" | html}}
    {{ $content }}
</description>

❯  A better control of the text displayed in the description

As we said before, Hugo’s default behavior for the description is the 70 first words of the page. It is possible to override this behavior by adding the full content. But if you want to control more precisely which text is added in the description, you can apply a manual summary splitting, cf the documentation on this topic.

To keep it short, it consists of adding a tag `

` to split what you want to add in the description and the rest of the page.


cf the documentation, these can be added by adding the following configurations to your config.toml:

  • copyright.
1
copyright = 'Β© 2023 ABC Widgets, Inc.'
  • author email and name.
1
2
3
[params.author]
email = "romain@laromierre.com"
name = "Romain Letourneur"

❯  add a rss icon to allow people to subscribe

Most of the Hugo themes (hugo-theme-stack that I am using on this blog, PaperMod or Coder for example…), are proposing the possibility to add social icons on the website (X ex-Twitter, LinkedIn and cie). Below is the syntax to add such a button for the theme hugo-theme-stack:

1
2
3
4
5
6
7
[[social]]
identifier = "rss"
name = "RSS"
url = "index.xml"

[social.params]
icon = "rss"

❯  bonus: tooling around the RSS

Some tools may be interesting during the construction of this RSS file. First, in the case where you are using Google Chrome, I particularly spotted two interesting extensions. The first one is the rss-feed-reader extension. After having installed the extension, if you type the path to your RSS XML file, it displays on a simple but elegant interface the last items on this feed, and also propose you to subscribe to this feed via several popular RSS apps ( “Feeder”, “Feedly”, “Feedbin”, “Inoreader”, and “Newsblur”). You can also add another RSS reader of your choice if your favorite is not on this list.

The RSS feed of this website displayed on rss-feed-reader
The RSS feed of this website displayed on rss-feed-reader

Google also proposes its extension for Chrome. Similar to the previous extension, it also proposes to display your feed and add it to a predefined list of apps or add your own if it is not in the default list. However, refreshing the design of this extension could be a good idea, even if it does the job.

Concerning the RSS feed reader, I use Feedly. I particularly appreciate its modern interface, the possibility of searching new RSS feeds directly from the interface, organizing the feeds by folders, etc. They also propose an excellent mobile app on Android and iOS! They propose free use of their app and subscription plans, adding some functionalities using IA.