66টি সোশ্যাল নেটওয়ার্কে RSS: Facebook, Instagram, X, LinkedIn, Telegram এবং আরও অনেক কিছু ব্লগ অ্যাফিলিয়েট যোগাযোগ
সাইন ইন ফ্রি শুরু করুন
Updated: 2026-10-07
Wagtail RSS Feed: Build It with Django Syndication and Auto-Post

Short answer: Wagtail does not ship an RSS feed, but it runs on Django, so the cleanest way to build a Wagtail RSS feed is Django’s syndication framework. Write a Feed class that returns your live, public blog pages ordered by publish date, use each page’s full_url as the link, add the route before Wagtail’s catch-all URL pattern, and make every link and image absolute. Once the feed validates, connect it to an auto-poster so each newly published page is shared on social media automatically.

Wagtail is a popular Django-based CMS used by newsrooms, universities, charities and product teams. Editors love its page tree and StreamField, and developers like that everything is plain Django underneath. That last point is what makes feeds simple: you do not need a Wagtail-specific plugin, because Django already has a well-tested feed generator. This guide shows how to wire it to Wagtail page models, how to handle rich text, images and multiple sites, how to keep the feed fresh behind a cache, and what to check before an automation tool starts reading it.

Does Wagtail have a built-in RSS feed?

No. A fresh Wagtail project has pages, images, documents and search, but no feed URL. That is a deliberate choice: Wagtail does not know which of your page types are articles, which date field matters or how much text you want to publish. You decide that in code.

There are three common approaches:

  • A Django Feed class with its own URL, such as /blog/feed/. Simple, explicit and easy to test. This is the approach used in most of this guide.
  • A route on the blog index page with Wagtail’s RoutablePageMixin, so every blog index in the page tree gets its own feed automatically.
  • A third-party package from PyPI that adds configurable feeds. These can save time, but check that the package supports your Wagtail and Django versions before you depend on it.

Whichever you choose, the output is a normal RSS 2.0 or Atom document that any reader or automation tool can use.

The page model the feed reads from

The examples assume a typical blog structure: a BlogIndexPage with BlogPage children. A minimal article model looks like this:

from django.db import models
from wagtail.models import Page
from wagtail.fields import RichTextField
from wagtail.admin.panels import FieldPanel


class BlogPage(Page):
    intro = models.CharField(max_length=300)
    body = RichTextField()
    cover = models.ForeignKey(
        'wagtailimages.Image', null=True, blank=True,
        on_delete=models.SET_NULL, related_name='+')

    content_panels = Page.content_panels + [
        FieldPanel('intro'),
        FieldPanel('cover'),
        FieldPanel('body'),
    ]

Two fields do most of the work in the feed. The intro field becomes the item description, so ask editors to write it as a real summary of one or two sentences. Wagtail’s own first_published_at field, which every page has, becomes the publication date. It is set automatically the first time a page goes live and does not change on later edits, which is exactly what a feed needs. In older projects the imports live under wagtail.core; the logic is the same.

Build the feed with Django’s syndication framework

Create blog/feeds.py:

from django.contrib.syndication.views import Feed
from django.utils.feedgenerator import Rss201rev2Feed
from wagtail.models import Site
from .models import BlogPage


class BlogFeed(Feed):
    feed_type = Rss201rev2Feed
    title = 'Example Blog'
    description = 'News and articles from Example'

    def __call__(self, request, *args, **kwargs):
        self.request = request
        self.site = Site.find_for_request(request)
        return super().__call__(request, *args, **kwargs)

    def link(self):
        return self.site.root_url + '/blog/'

    def items(self):
        return (BlogPage.objects.live().public()
                .in_site(self.site)
                .order_by('-first_published_at')[:20])

    def item_title(self, item):
        return item.title

    def item_description(self, item):
        return item.intro

    def item_link(self, item):
        return item.full_url

    def item_pubdate(self, item):
        return item.first_published_at

    def item_updateddate(self, item):
        return item.last_published_at

A few details are worth understanding rather than copying:

  • live() এবং public() exclude drafts, unpublished pages and pages behind a view restriction such as a password or login. Without them, a private page can leak into the feed and from there onto social media.
  • in_site() keeps the feed limited to the site the request came to, which matters as soon as one Wagtail installation serves several domains.
  • full_url returns the absolute address of the page including scheme and domain. Feed readers and auto-posters see links out of context, so relative paths do not work for them.
  • The limit of 20 items keeps the feed small and fast. Older posts stay on the website; the feed only needs the recent ones.

Note that Django’s feed view uses the separate django.contrib.sites framework, or the request host when that app is not installed, to complete relative links. Wagtail has its own Site model, and the two are not connected. Returning absolute URLs yourself, as above, avoids any confusion between them.

Add the URL before Wagtail’s catch-all pattern

Wagtail serves pages through a catch-all URL pattern, so the feed route has to come first in your project’s urls.py:

from django.urls import path, include
from wagtail import urls as wagtail_urls
from blog.feeds import BlogFeed

urlpatterns = [
    # admin, documents and other routes ...
    path('blog/feed/', BlogFeed(), name='blog_feed'),
    path('', include(wagtail_urls)),
]

If the feed line comes after the Wagtail include, Wagtail tries to find a page called feed under your blog and returns a 404. This ordering mistake is the most common reason a new Wagtail feed does not work.

Pick the address once and keep it. Every reader, aggregator and automation tool that subscribes stores the URL, and changing it later means updating all of them. Advice on choosing it is in which RSS feed URL to use.

A feed per blog index with RoutablePageMixin

Larger sites often have several sections, such as news, events and research, each with its own index page. Instead of writing a URL for each, make the index page routable:

from wagtail.contrib.routable_page.models import RoutablePageMixin, route


class BlogIndexPage(RoutablePageMixin, Page):

    @route(r'^feed/$')
    def feed(self, request):
        return SectionFeed(self)(request)

যোগ করুন wagtail.contrib.routable_page to INSTALLED_APPS, and give SectionFeed a constructor that stores the index page so its items() method can return BlogPage.objects.live().public().child_of(self.index). Every index page now answers at its-url/feed/, so /news/feed/ এবং /research/feed/ exist without extra configuration.

Section feeds are useful well beyond readers. You can send research updates to LinkedIn, event announcements to a Telegram channel and everything to Mastodon, each from its own feed. The idea is explained in category filtering for auto-posting.

Rich text, StreamField and full-content feeds

A summary from the intro field is enough for most feeds and works best for social posts, where only the first sentences are visible. If you also want full content for feed readers, there are two traps.

First, Wagtail stores rich text in an internal format in which links to pages and documents are references rather than URLs. Always convert it before output:

from wagtail.rich_text import expand_db_html

def item_description(self, item):
    return expand_db_html(item.body)

Second, the converted HTML may still contain site-relative links and image addresses, such as /media/images/photo.width-800.jpg. Inside a feed they break. Either rewrite them to absolute URLs with a small helper that prefixes self.site.root_url, or serve media from a storage backend or CDN that already returns absolute URLs.

For StreamField bodies, render the blocks to HTML with the field’s own rendering and apply the same URL fix. Keep embeds in mind: video embeds and custom blocks may produce markup that feed readers strip, so test with a real reader. When you need both, a common pattern is a summary feed for automation and a separate full-text feed for readers. The trade-offs are covered in full-text vs excerpt RSS feeds.

Add the cover image

Social posts with a good picture get far more attention than plain links. Auto-posting tools look for an image in the feed item and in the Open Graph tags of the linked page, so give them both.

In the feed, an enclosure is the most widely understood way to attach an image. Django supports it through three item methods:

def item_enclosure_url(self, item):
    if item.cover:
        r = item.cover.get_rendition('fill-1200x630')
        return self.request.build_absolute_uri(r.url)

def item_enclosure_mime_type(self, item):
    return 'image/jpeg'

def item_enclosure_length(self, item):
    return 0

build_absolute_uri turns a relative rendition URL into an absolute one and leaves an absolute CDN URL unchanged. Use the real file size if you have it, and set the MIME type to match the rendition format. Then make sure your page template outputs an og:image meta tag with the same rendition, so link previews show the same picture. More on choosing the image is in how to control which image gets auto-posted.

RSS or Atom

Django can produce either format from the same class. Switch the output by changing one line:

from django.utils.feedgenerator import Atom1Feed

class BlogAtomFeed(BlogFeed):
    feed_type = Atom1Feed
    subtitle = BlogFeed.description

Atom uses subtitle instead of description and makes good use of the updated date. Most automation tools read both formats. If you are unsure which one to offer, offer RSS 2.0 and add Atom only if someone asks for it; the differences are summarised in Atom vs RSS for auto-posting.

Feed elementWagtail sourceWhy it matters
linkpage.full_urlAbsolute URL that works outside the site
pubDatefirst_published_atStable date that does not change on edits
guidDefaults to the linkKeeps items unique for readers and tools
descriptionintro or expanded rich textThe text shown in readers and posts
enclosureImage renditionThe picture used in social posts
Item filterlive(), public(), in_site()Keeps drafts and private pages out

Scheduled publishing, edits and caching

Wagtail lets editors schedule pages with a go-live date. A scheduled page is not live until the publish_scheduled management command runs (named publish_scheduled_pages in older releases), so run it from cron every few minutes. Until then the page is not in the feed, which is what you want: anything that appears in the feed may be shared immediately.

Edits are a separate matter. The GUID that Django writes defaults to the item link, so changing a page’s slug after publication changes its GUID, and automation tools may treat the edited page as a new post. Decide slugs before publishing, or define item_guid to return something stable such as the page ID combined with your domain. Why this matters is explained in why a feed auto-posts the same article twice.

Caching is the last piece. If you use Wagtail’s frontend cache invalidation with a CDN or reverse proxy, it purges a page’s URLs when the page is published, but the feed lives at a different URL. Either give the feed a short cache time, or override get_cached_paths() on the index page so the feed path is purged as well. Django’s per-view cache can also wrap the feed view, but keep its timeout short.

Advertise the feed and validate it

Add an autodiscovery link to the head of your base template so browsers, readers and tools can find the feed from any page:

<link rel="alternate" type="application/rss+xml"
      title="Example Blog" href="/blog/feed/">

Then validate. Open the feed in a browser, run it through the W3C Feed Validation Service, and check the details a validator does not judge:

  • Every link and image URL starts with your real https domain.
  • The newest page is first, and the dates are correct in your time zone.
  • No draft, private or test page appears.
  • The response is served as application/rss+xml; Django sets this for you, but a proxy can change it.
  • Special characters and emoji in titles display correctly.

The framework’s options are documented in the Django syndication feed framework reference, and Wagtail’s page query methods in the Wagtail documentation. A quick way to inspect headers and status codes is described in debugging an RSS feed with curl.

How PostRSS works with a Wagtail site

PostRSS has been publishing RSS and Atom feeds to social networks since 2014. Paste the address of your Wagtail feed, or of each section feed, connect your accounts and choose how posts are built from the title, description or page title. PostRSS checks each feed as often as every minute and shares new pages, with their image and link, to the channels you choose among 66 supported networks, messengers, team chats and blogs, including LinkedIn, Mastodon, Bluesky, Telegram, Discord and DEV. Keyword filters, UTM parameters, hashtags from categories and posting windows let you adjust each channel. Everything it does is listed on the PostRSS features page, and plan limits are on the pricing page. More developer guides are under the Technical Guide tag.

Related reading

The bottom line

A Wagtail RSS feed is a small Django Feed class: return live, public pages from the current site, newest first, use full_url for links and first_published_at for dates, and register the route before Wagtail’s catch-all pattern. Add a cover image as an enclosure, make every URL absolute, keep the GUID stable and the cache short. Validate it once, add an autodiscovery link, and every page you publish in Wagtail can reach your social channels without anyone copying links by hand.

FAQ

Does Wagtail generate an RSS feed automatically?

No. Wagtail has no feed out of the box, but because it is built on Django you can create one with Django’s syndication framework in a few dozen lines of code.

Why does my Wagtail feed URL return a 404?

The feed route is probably listed after the Wagtail catch-all pattern in urls.py. Move it above the include of Wagtail’s URLs so Django matches it first.

How do I keep drafts and private pages out of the feed?

Filter the queryset with live() and public(). Live excludes drafts and unpublished pages, and public excludes pages with a password, login or group restriction.

Can each section of a Wagtail site have its own feed?

Yes. Add RoutablePageMixin to the index page model and define a feed route, so every index page answers at its own feed address with only its child pages.

Why do images in my Wagtail feed not show?

Image renditions and rich text often use site-relative URLs. Convert them to absolute URLs with build_absolute_uri or the site root URL before they go into the feed.

New guides, once a month

What changed in the networks, what broke, and how to fix it before it costs you reach.

We send a confirmation e-mail first. Unsubscribe any time.

আমাদের টিমের আরও টুল

PostRSS-এর পেছনের টিম Internet Solutions-এর তৈরি। প্রতিটি পণ্য নিজের মতো করে আপনার সময় বাঁচায়।

ওয়েবসাইটের জন্য AI লাইভ চ্যাট Talkmio আপনার ওয়েবসাইট আপনার নিজের কনটেন্ট থেকে, দর্শকের ভাষায়, 24/7 উত্তর দেয়। ফ্রি প্ল্যান · কার্ড লাগবে না AI সহকারী Ask Mio চ্যাট, কোড, ডিজাইন, লেখা ও গবেষণা। প্রতিটি কাজের জন্য Mio সেরা মডেলটি বেছে নেয়। ফ্রি প্ল্যান ব্লগ ও সোশ্যাল মিডিয়ার জন্য AI অটোপাইলট AI Blog Autopilot AI 2,000–3,000 শব্দের SEO আর্টিকেল লেখে এবং প্রতিটি 58+ সোশ্যাল নেটওয়ার্কে শেয়ার করে। প্রথম 3টি আর্টিকেল ফ্রি ওয়েবসাইট হেলথ চেক Site AI Audit SEO, গতি, SSL, নিরাপত্তা ও ইমেইল সেটআপ এক রিপোর্টে, কোনটা আগে ঠিক করতে হবে সেই ক্রমে। প্রথম অডিট ফ্রি গভীর SEO ক্রল Site SEO AI Audit AI সার্চে দৃশ্যমানতাসহ 7টি ক্ষেত্রে পূর্ণ SEO ক্রল, প্রভাব অনুযায়ী সাজানো সমাধানসহ। প্রথম অডিট ফ্রি RSS ও পণ্য ফিড RSS Feed Creator যেকোনো ওয়েব পেজ থেকে RSS তৈরি করুন, সঙ্গে Google ও Meta-র জন্য পণ্য ফিড যা নিজে থেকেই আপডেট হয়। ফ্রি প্ল্যান ওয়েব ডেভেলপমেন্ট ও SEO Internet Solutions ওয়েবসাইট, ই-শপ ও কাস্টম সিস্টেম — আমাদের টিম ডিজাইন করে, তৈরি করে ও পরিচালনা করে। 2011 থেকে