
Short answer: VitePress has no built-in RSS feed, but it gives you everything needed to generate one at build time. In .vitepress/config, add a buildEnd hook, load your posts with createContentLoader, build the XML with the feed package and write it to the output folder as feed.rss o feed.xml. Use your full site address for links and real dates from front matter, add a discovery link to the head, and an RSS auto-poster can share every new post automatically.
VitePress is the Vue-powered static site generator behind many documentation sites, developer blogs and project homepages. It is fast, simple to configure and produces static files that host anywhere. What it does not produce is an RSS feed, because its focus is documentation. Yet documentation sites publish changelogs, release notes and blog posts that people want to follow, and feeds are how readers, team chats and social posting tools follow them. This guide shows the recommended build-time approach, the details that most often go wrong, and how to use the feed for automated announcements.
Decide the scope first. For most VitePress sites, the feed should cover a blog, news or changelog folder, not every documentation page. A good feed:
For background on the elements, see what guid and pubDate actually do.
npm install -D feed
The feed package generates RSS 2.0, Atom and JSON Feed from one object and escapes all text. Writing XML by hand in a build script is possible, but escaping mistakes are easy to make and hard to notice until a title with an ampersand breaks everything.
VitePress calls buildEnd after the site is built, which is the right moment to write extra files. createContentLoader reads Markdown files matching a pattern and returns their URL, front matter and, optionally, an excerpt and rendered HTML.
// .vitepress/config.ts
import { defineConfig, createContentLoader, type SiteConfig } from 'vitepress'
import { Feed } from 'feed'
import { writeFileSync } from 'node:fs'
import path from 'node:path'
const hostname = 'https://example.com'
export default defineConfig({
title: 'Example Docs',
cleanUrls: true,
async buildEnd(config: SiteConfig) {
const feed = new Feed({
title: 'Example Docs Blog',
description: 'Release notes and articles from Example Docs',
id: hostname + '/',
link: hostname + '/',
language: 'en',
copyright: 'Example Ltd',
feedLinks: { rss: hostname + '/feed.rss' },
})
const posts = await createContentLoader('blog/*.md', {
excerpt: true,
render: true,
}).load()
posts
.filter((p) => !p.frontmatter.draft)
.sort((a, b) => +new Date(b.frontmatter.date) - +new Date(a.frontmatter.date))
.slice(0, 30)
.forEach(({ url, frontmatter, excerpt, html }) => {
const link = hostname + url
feed.addItem({
title: frontmatter.title,
id: link,
link,
description: frontmatter.description || excerpt,
content: html,
date: new Date(frontmatter.date),
})
})
writeFileSync(path.join(config.outDir, 'feed.rss'), feed.rss2())
},
})
This is close to the pattern VitePress’s own documentation suggests for feeds. A few notes:
blog/*.md limits the feed to the blog folder. Use changelog/*.md or several patterns for other sections.--- separator in the body. If you prefer explicit summaries, use a description front matter field, as the example does.draft: true front matter flag; adapt it to your own convention.config.outDir, which is .vitepress/dist by default, so it is deployed with the rest of the site.If the feed only includes summaries, you can drop render: true y content, which makes builds faster on large sites. For the trade-off between summaries and full text, see full-text vs excerpt RSS feeds.
createContentLoader returns site-relative URLs such as /blog/release-2-0. Feeds need absolute links, so the example prepends hostname. Three settings affect the result:
cleanUrls: true, URLs have no .html suffix. Your host must serve them correctly; otherwise feed links return 404 even though the site navigation works.After deployment, open the feed and click the first item. It should open the post exactly as visitors see it. Problems with relative links are described in relative URLs in RSS feeds.
The feed needs a real publication date for each post. Put it in front matter:
---
title: Version 2.0 released
description: A new plugin API, faster builds and two breaking changes to plan for.
date: 2026-10-11
---
Some sites use lastUpdated from Git instead, but that reflects edits, not publication, and in CI it can be misleading if the pipeline uses a shallow clone. For a feed of announcements, explicit front matter dates are the reliable choice. Posts with dates in the future appear in the feed as soon as you build; if you prepare posts in advance, filter them out with a date comparison in the build hook and schedule regular rebuilds. More date pitfalls are listed in RSS date format errors.
The feed carries text; social networks also need an image. Most auto-posters look for an image in the feed item first and then read the page’s og:image tag. With VitePress you can add page-specific Open Graph tags with the transformHead hook or with head entries in front matter:
---
title: Version 2.0 released
head:
- - meta
- property: og:image
content: https://example.com/images/release-2-0.png
---
You can also pass an image property to feed.addItem() so the image is included in the feed itself. Use images at least 1200 pixels wide with absolute URLs. See how to control which image gets auto-posted.
Documentation sites often have more than one stream of news. A product might publish a blog with tutorials, a changelog with every release and translated docs in several languages. Each stream has a different audience, so it usually deserves its own feed:
createContentLoader twice with different patterns and write two files, for example blog.rss y changelog.rss. Users who only care about releases can follow one without the other./de/. Generate one feed per locale from that folder, with a matching language value, and send each to the channels for that audience.Give every feed a clear title, add an autodiscovery link for each, and keep their addresses stable once tools subscribe to them. Routing different topics to different accounts is covered in RSS feed category filtering.
Add an autodiscovery link through the head option in the config, so browsers, readers and tools can find the feed from any page:
head: [
['link', { rel: 'alternate', type: 'application/rss+xml',
title: 'Example Docs Blog', href: '/feed.rss' }],
],
A visible RSS link in the blog index or footer, for example through the theme’s social links or a custom component, helps human subscribers too. For more on discovery, see Autodetección de feeds RSS.
Static hosts choose the content type from the file extension. Most map .xml to an XML type, and many map .rss to application/rss+xml, but not all. If a host serves the feed as application/octet-stream, some readers download it instead of parsing it. Either name the file feed.xml, or add a header rule on your host, for example in Netlify’s _headers file or a Cloudflare Pages rule, setting Content-Type: application/rss+xml. Check with curl -sI https://example.com/feed.rss. Our article on the RSS Content-Type header explains why this matters.
npm run docs:build (or your build script) and check that the feed file exists in the output folder;The VitePress data loading guide documents createContentLoader and its options.
| Symptom | Cause | Fix |
|---|---|---|
| No feed after deploy | File written outside outDir | Write to config.outDir |
| Links without domain | Loader URLs used as they are | Prepend the full hostname |
| Links miss the subfolder | base not reflected | Include the base path |
| Links return 404 | cleanUrls unsupported by host | Configure the host or disable clean URLs |
| Invalid dates | Missing or malformed front matter dates | Use ISO dates in front matter; let the package format them |
| Feed downloads instead of opening | Wrong content type for .rss | Use .xml or a header rule |
VitePress sites are often maintained by developers who would rather ship than post. With a feed, announcements become configuration:
Because the site is static, a post reaches the networks only after the build is deployed and the posting tool’s next check. Deploy first, and the rest happens automatically.
PostRSS has been publishing RSS and Atom feeds to social networks and team tools since 2014. Paste the address of your VitePress feed, connect your accounts and choose the post format. PostRSS checks the feed as often as every minute and shares each new post, with its image and link, to the networks you choose among 66 supported networks, including Mastodon, Bluesky, Discord, Telegram, Mattermost, Zulip and DEV, plus webhooks for Slack, Microsoft Teams, Zapier and n8n. Keyword filters, UTM parameters and posting windows help you tailor each channel. See the PostRSS features page and the plan limits on the pricing page. More developer guides are under the Technical Guide tag.
A VitePress RSS feed is a short buildEnd hook: load posts with createContentLoader, build the XML with the feed package and write it into the output folder. Use the full hostname for links, mind base y cleanUrls, take dates from front matter and check the content type on your host. Add a discovery link, validate once, and every release note and post can reach your channels automatically.
No. VitePress focuses on documentation and has no built-in feed. You generate one at build time in the buildEnd hook, typically with createContentLoader and the feed package from npm.
Write it into the build output folder, available as config.outDir in the buildEnd hook. Then it is deployed with the rest of the site and served at the matching URL, such as /feed.rss.
The content loader returns site-relative URLs. Prepend your full https hostname, and the base path if the site lives in a subfolder, before passing links to the feed.
Both work if your host serves the right content type. If the host does not recognise the .rss extension, use feed.xml or add a header rule that sets application/rss+xml.
Yes. Point an RSS auto-poster at the feed and connect Discord, Slack through a webhook, or another team chat. Each new release note is then announced without manual copying.
What changed in the networks, what broke, and how to fix it before it costs you reach.
Creadas por Internet Solutions, el equipo detrás de PostRSS. Cada una te ahorra tiempo a su manera.