This module provides extra abilities for implementing RSS feeds.
It's pretty similar to module-feed,
but have support for nuxt-content.
If you need fully customized feeds, you can freely choose any feed module (this or the one mentioned above). But this module can be more flexible.
nuxt-contentnuxt-contentDefault settings are:
{
defaults: {
common: true,
routes: true,
mapping: true,
mappingTemplates: true,
},
feeds: {
common: {
revisit: '6h',
fixDateFields: true,
feed: { title: 'Generated title by nuxt-feedme!' },
collections: ['content'],
templateMapping: ['', 'meta', 'meta.feedme'],
mapping: [
['link', 'path'],
],
},
routes: {
'/feed.atom': { type: 'atom1' },
'/feed.json': { type: 'json1' },
'/feed.xml': { type: 'rss2' },
}
},
}
By design, Nuxt will merge default settings and user-provided ones. And sometimes you'll need to omit defaults in favor of your own settings. To do this, just set false to needed default.
The fixDateFields option affects only created Feed Items (date and published fields).
Feedme supports the following general and specialized hooks:
feedme:handle[${PATH}]feedme:handlefeedme:handle:content:before[${PATH}]feedme:handle:content:beforefeedme:handle:content:query[${PATH}]feedme:handle:content:queryfeedme:handle:content:item[${PATH}]feedme:handle:content:itemfeedme:handle:content:after[${PATH}]feedme:handle:content:afterWhere PATH is the feed route (e.g., /feed.xml or any user-defined).
Content hooks are executed only when the default handle doesn't create a feed.
The feed creation in feedme:content* hooks prevents Feedme from automatic creation via content module.
You may use a specialized hook for creating a custom feed, or "escape" route from your custom creation.
import type { NitroApp } from 'nitropack'
export default (nitroApp: NitroApp) => {
nitroApp.hooks.hook('feedme:handle', async ({ context: { event, routeSettings }, feed: { obtain } }) => {
// Note: You need to manually escape content paths when use both manual and content approaches
const escapeRoutes = new Set(['/content.xml', '/pages.json'])
if (escapeRoutes.has(event.path)) return
// Note: Since there's no specialized hooks for atom feed, general will create feed object
const feed = obtain({ title: `Default feed for '${event.path}'`, ...routeSettings.feed })
feed.addItem({ date: new Date('2025-09-20'), link: '/', title: 'General hook article' })
})
nitroApp.hooks.hook('feedme:handle[/feed.xml]', async ({ context: { event }, feed: { obtain } }) => {
// Note: Specialized hook is always called before general
const feed = obtain({ title: `Special feed for '${event.path}' route` })
feed.addItem({ date: new Date('2025-09-21'), title: 'Exclusive for xml (from specialized hook)' })
})
}
You still can modify the content feed via content hooks.
feedme:handle:content:before* hooks to setup Feed before any interaction.feedme:handle:content:query* hooks to provide custom queries or collections (collections are ignored when queries are provided).feedme:handle:content:item* hooks to manipulate the feed item candidate or delete (discard) it.feedme:handle:content:after* hooks to manipulate over completed feeds when you need it.See examples in playground/server/plugins/feed.ts.
Mapping is used for linking feed
item keys to the paths in parsed content.
BREAKING CHANGE: Since v2, the third argument is no longer supported.
Use feedme:handle:content:item* hooks to modify data
(raw parsed content via raw or item candidate via set, get and del).
The Feedme module provides default mapping as is and template roots for '' (root),
'meta' (nuxt parsed content field for user object in .md file),
'meta.feedme' (nested object in .md file object).
Also, Feedme provides additional mapping ['link', 'path']
(nuxt default field link in parsed content object to feed item path field).
With template roots, it is possible to automatically create a feed item
from the .md content page (see the playground directory).
For simplicity, Feedme sets feeds.common.fixDateFields to true,
which enables string-to-date conversion for candidate items before feedme:handle:content:item* hooks.
Previously known as tags.
The replace field is an array of pairs.
The first item is string, which is considered a serialized RegExp object and used
for searching replacement in parsed content object values (with recursion).
The second item is an actual string that is being used to replace all matched RegExp.
Most settings can be set in common and per route.
{
feeds: {
common: {
replace: [[/^(?=\/)/.toString(), baseUrl]],
},
}
}
nuxt-feedme dependency to your project.yarn add -D nuxt-feedme
pnpm add -D nuxt-feedme
npm install --save-dev nuxt-feedme
nuxi modulenpx nuxi@latest module add nuxt-feedme
nuxt-feedme to the modules section of nuxt.config.tsexport default defineNuxtConfig({
modules: [
// After nuxt content
'@nuxt/content',
'nuxt-feedme'
]
})
That's it! You can now use nuxt-feedme in your Nuxt app ✨
For local development is highly recommended to use docker:
docker compose --profile develop up
Optional: run with detach (flag -d) if you want to release you session.
Alternative:
# Install dependencies
yarn install
# Run playground
yarn run dev --host '0.0.0.0'
# Run prepack to make sure, that module is ready
yarn run prepack
Warning: Please, use conventional commits, otherwise you changes maybe rejected or pushed in alternative branch.