Ibrahim Sowunmi

How to Embed a RSS Substack Feed into Your Hugo Static Site

TL:DR; If you know hugo. Copy the code. It’s styled with tailwind.

Imagine a scenario. Let’s say you want to update your painstakingly developed static site with your latest Substack posts? You’re using the POSSE philiosophy. Sounds troublesome without a server to make API calls right? Today, we’re diving into a nostalgic yet incredibly effective technology: RSS feeds. Specifically, I’ll guide you through embedding an RSS feed into your Hugo static site, seamlessly integrating your Substack content. No complex API calls, just straightforward, practical steps.

Before we delve into the process, let’s briefly explain our tools. RSS to retrieve our data. Hugo shortcodes for templating, allowing you to render Dynamic HTML from your Markdown content. And last, but not least, Hugo Pipes, the powerhouse behind this operation. They retrieve information for your static site without needing a server.

What is RSS? RSS, which stands for Really Simple Syndication, is a technology that helps people keep up with their favourite websites and blogs without having to visit each one individually. Think of it like a news feed for the internet. Just like you get updates from friends on social media, RSS delivers updates from websites.

Hugo Shortcodes? These are your building blocks. Think of them as prebuilt HTML templates that take information from your Markdown to generate Dynamic HTML. They’re the foundation of embedding your RSS feed into your site.

Hugo Pipes? This is where the magic happens. Pipes allow you to fetch and display your RSS feed without the need for a server. It’s a straightforward process using resource.GetRemote, which brings efficiency and simplicity to your site.

I’ll share the process of setting up the shortcode, fetching the feed with Hugo Pipes, and integrating it into your Markdown to get you up and running ASAP. Here’s what the code looks like:

This is some stylised (TailwindCSS) shortcode. Remove the CSS as needed. Saved in shortcodes/substack.html.

{{ if .Get "url" }}
{{ $url := .Get "url" }}
{{ $limit := .Get "limit" }}

<div class="py-8">
    {{ with resources.GetRemote $url | transform.Unmarshal }}
    {{ range first $limit .channel.item }}
    <div class="grid grid-cols-1 md:grid-cols-2 bg-white shadow-lg border border-gray-200 rounded-lg p-4 cursor-pointer mb-6 md:mb-10" onclick="window.location='{{ .link }}'">
        <div class="flex flex-col p-4">
            <h2 class="text-xl font-semibold">{{ .title | htmlUnescape }}</h2>
            <p class="text-slate-400 muted text-sm">{{ dateFormat "January 2, 2006" .pubDate }}</p>
            <p class="text-gray-800 mb-4">{{ .encoded | safeHTML | truncate 300 }}</p>
        </div>
        <div class="flex justify-center items-center">
            {{ with .enclosure }}
            {{ $url := index . "-url" }}
            <img src="{{ $url }}" alt="{{ .title | htmlUnescape }}" class="object-contain max-h-72 rounded-xl" style="border-radius: 20px;">
            {{ end }}
        </div>
    </div>
    {{ end }}
    {{ end }}
</div>
{{ end }}

And below is how you would call it in Markdown. Very Elegant

---
title: "Example"
---
{{ <substack url="https://ibrahimsowunmi.substack.com/feed" limit="5" > }}

Important: Change the alignment of the opening and closing tags to or it won’t render

It takes the URL to the XML in the url param, and the number of items to render in limit param.

Once set up, your website automatically updates with your latest Substack posts each time you deploy.

And this is what the output should look like. Mobile first clickable cards.

See it in action

Now, there’s one important aspect to consider. Say you update the RSS feed, what happens? The GetRemote is run for each build and deploy. If you’re not frequently updating your website but regularly posting on Substack, you might find your site lagging behind your content. A solution? Use Netlify webhooks for automated builds. This ensures your website is always in sync with your latest posts. If help is needed with this send an email :)