How to create feed pages

Goal

In this guide we will learn how to configure a feed, how to add/remove pages for specific feeds, and how to add feed contents to a layout template.

What is a web feed?

A feed is a data format for frequently updated content. The list of stories on your Facebook home page is called the Feed. When you scroll Instagram or TikTok, you are interacting with a feed.

Although feeds have been popularized by social media, the origin of the feed predates all social media platforms. The rise of "blogging" and the growing number of interesting websites to keep up with in the mid-to-late 1990's led to the invention of a feed format that was eventually called "RSS". The availability of RSS feeds led to the creation of apps like NetNewsWire that let users subscribe to feeds from multiple websites and display them in a manner very similar to the social media experiences we have today. While RSS feeds are still widely used for blogs and other text-based content, the most popular use case born out of this original notion of a feed is podcasting, which was made possible by linking to MP3 files from an RSS feed.

Fast forward to today and there are a few popular feed formats in use – RSS, Atom, and JSON Feed – each with their own distinct advantages.

How do feeds work?

There are effectively two primary components to a web feed: feed files, and feed pages.

In theory, a web feed is a single data file containing a list of links to new content, along with some metadata including a title, description, and summary. However, feed files are typically formatted for applications, not people (e.g. the feed for this website). In practice, most websites also present the content of web feeds via feed pages, like a blog (e.g. the blog for this website).

Let's see how these two components work together in the following guide.

Guide

STEP 1: Add a feed
If you don't already have a /blog/ page, let's create one by adding a content/blog/index.md file. content/blog/index.md
1---
2created_at: 2025-05-22T15:00:00-07:00
3title: My first blog
4description: Blog posts should appear on this page
5---

Now let's add a page.feed property to content/blog/index.md and give it a title.

content/blog/index.md
1---
2created_at: 2025-05-22T15:00:00-07:00
3title: My first blog
4description: Blog posts should appear on this page
5feed:
6    title: My first blog
7---

That's it! You've just created your first feed. 👏 Now run hyperctl build or hyperctl server and you should see a feed file at /blog/atom.xml.

STEP 2: Add feed filters
You may have noticed in the first exercise that there are already pages in your shiny new feed. That's because we have created a feed with no filters, so it automatically includes every page1 in the website.

To control which pages appear in our feed, we need to add a filter. HyperTemplates feeds support tag-based and path-based filtering. Tag-based filters are useful for pulling in specific pages from multiple sections of a website (see page.feed.tags). Path-based filters are great for pulling in all pages with paths matching a specific pattern (e.g. /blog/*). For most blogs, a simple path-based filter is the right tool.

Let's add a path-based filter to our blog feed.

content/blog/index.md
1---
2created_at: 2025-05-22T15:00:00-07:00
3title: My first blog
4description: Blog posts should appear on this page
5feed:
6    title: My first blog
7    paths:
8      - ^/blog/*
9---

That's it! Now just run hyperctl build or hyperctl server and you should only see blog posts in /blog/atom.xml.

If you don't see any pages, lets create one by adding a content/blog/hello-world/index.md file.

content/blog/hello-world/index.md
1---
2created_at: 2025-05-22T15:00:00-07:00
3title: Hello, world!
4description: My first blog post
5---
6
7Hello, my name is __________. :wave:

Now just run hyperctl build or hyperctl server and you should see the new "Hello, world!" blog post in the /blog/atom.xml feed.

STEP 3: Add/remove pages
So far we've covered how to create a feed, and how to control what pages are included in feeds with feed filters. Now let's see how we can add/remove individual pages to and from feeds.

To remove a page from all feeds, configure the page.unlisted property.

content/blog/hello-world/index.md
1---
2created_at: 2025-05-22T15:00:00-07:00
3title: Hello, world!
4description: My first blog post
5unlisted: true
6---
7
8Hello, my name is __________. :wave:

To add a page to a tag-based feed, configure the page.tags property.

content/blog/hello-world/index.md
1---
2created_at: 2025-05-22T15:00:00-07:00
3title: Hello, world!
4description: My first blog post
5tags:
6  - blog
7---
8
9Hello, my name is __________. :wave:

Alternatively, for path-based feeds such as the feed we configured in STEP 2, simply add a new page at a path that matches the path-based filter. For example, to add a page to a feed with a filter like ^/blog/*, create a new page data file at content/blog/hello-again/index.md.

That's all there is to it! Use path-based and tag-based filters to configure feeds. And use the page.tags & page.unlisted properties to configure pages.

STEP 4: Add a feed layout
To add a feed page, let's create a new layout.

Create a layouts/blog.html file and add the following contents:

layouts/blog.html
 1<!DOCTYPE html>
 2<html lang='en-US'>
 3    <head>
 4        <meta ht-include='partials/head' />
 5  
 6        <!-- Layout Properties -->
 7        <meta name='layout:name' content='blog'/>
 8  
 9        <!-- Layout Components -->
10        <script src='/js/components/relative-time.js' defer></script>
11  
12        <!-- Layout Styles -->
13        <style id='layout'></style>
14    </head>
15    <body>
16        <header ht-include='partials/hero'></header>
17        <main>
18            <feed-entry ht-template='entry:page.feed.pages;site:site'>
19                <post-meta>
20                    <h2><param ht-param='entry.title' /></h2>
21                    <p ht-if='entry.author,site.author'>
22                        By <param ht-param='entry.author.name' default='Team HyperTemplates'>,
23                        <time ht-attrs='datetime:entry.updated_at,entry.created_at'></time>
24                    </p>
25                </post-meta>
26                <post-content>
27                    <param ht-param='markdown:entry.summary,entry.content' />
28                </post-content>
29                <a ht-attrs='href:entry.path' ht-if='entry.path'>Continue reading...</a>
30            </feed-entry>
31        </main>
32        <footer ht-include='partials/footer'></footer>
33    </body>
34</html>

The page.feed.pages template data property is a collection of pages matching page feed filters. Each page in page.feed.pages will contain all page properties.

The highlighted portion of this layout uses an ht-template attribute to create a nested template for each page as an entry variable:

1ht-template='entry:page.feed.pages;site:site'

This example also passes in site template data to the nested template so that site.author.name can be used as a fallback when no entry.author.name is available (see line 22).

STEP 5: Add a feed page
Let's use our new feed layout to display the contents of our feed, making a feed page.

Add a page.layout property to our feed page:

content/blog/index.md
 1---
 2created_at: 2025-05-22T15:00:00-07:00
 3layout: blog
 4title: My first blog
 5description: Blog posts should appear on this page
 6feed:
 7    title: My first blog
 8    paths:
 9      - ^/blog/*
10---

That's it! Now just run hyperctl build or hyperctl server and you should see feed contents at /blog/.

Discussion

In this guide, we learned how feeds work in HyperTemplates. We created a feed and learned how to customize feeds using feed filters, and how to add/remove individual pages. We created a simple feed page layout and used it to create a feed page.

Do you have any questions and/or feedback about this guide? Join the @hypertexting.community and visit the "Guides" category to let us know.


  1. Technically speaking, a feed with no filters will include all pages except the feed page itself, and unlisted pages (see page.unlisted, or continue to STEP 3 for more information).Â â†Šī¸Ž

Edit this page on GitHub

đŸ’Ŧ Join the community

Stay up-to-date with the lastest releases and other news from Team HyperTemplates. Ask the developers questions, get help from the community, and share your creations! 🎨