Skip to content

feat: provide rss, atom and json feeds for the blog#2562

Draft
Kiwow wants to merge 5 commits intonpmx-dev:mainfrom
Kiwow:rss
Draft

feat: provide rss, atom and json feeds for the blog#2562
Kiwow wants to merge 5 commits intonpmx-dev:mainfrom
Kiwow:rss

Conversation

@Kiwow
Copy link
Copy Markdown
Contributor

@Kiwow Kiwow commented Apr 17, 2026

I'm opening this as a draft so that progress on it is transparent. Feedback is appreciated even before it's ready!

🔗 Linked issue

Resolves #2489

The plan

  • Generate RSS, Atom and JSON feeds from blog posts using the feed package
    • Generate these at build time
    • Use the data that modules/blog.ts is creating in .nuxt/blog/posts.ts, possibly in the same module setup
    • Use prerendered routes, similarly to how opensearch.xml gets served (thanks to @t128n for the pointer on this)
  • Serve the feeds at "/rss.xml", "/atom.xml" and "/feed.json" respectively
    • Serve with types "application/rss+xml", "application/atom+xml" and "application/feed+json"
  • Provide <link rel="alternate"> elements for readers to find the feeds
  • Test that this works (with an e2e test?)

Checklist

Before merging, I need to make sure that:

Issues / obstacles:

The feed package currently doesn't support JSON Feed 1.1, which added support for multiple authors. This means it silently throws away all but the first author we specify in an the author array. Manually parsing the object after it gets generated and adding in the other authors is an option, but then we'd be lying about the version that we're serving. Alternatively, it shouldn't be that hard to write the JSON Feed serializer ourselves (the feed implementation is a bit over 100 lines of code)

RSS (the spec) seemingly doesn't support multiple authors at all, or just in convention, where you put everyone into an <author> tag. I'll have to try and test some readers / find how feeds handle multiple authors to figure out a good solution. Either way, the feed package includes multiple <author> tags, which seems to be valid in Atom but not in RSS.

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 17, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Apr 17, 2026 11:04pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Apr 17, 2026 11:04pm
npmx-lunaria Ignored Ignored Apr 17, 2026 11:04pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 17, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 293e9c97-1219-4c4d-979a-fa6d1e269742

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

⚠️ Duplicate Dependencies (found: 20, threshold: 4)

📦 Package 📋 Versions
h3
5 versions
  • root@
    • @nuxt/fonts@0.14.0
      • fontless@0.2.1
        • unstorage@1.17.5
          • h3@1.15.11

  • root@
    • @nuxt/fonts@0.14.0
      • h3@1.15.8

h3@2.0.1-rc.11
h3@2.0.1-rc.16
h3@2.0.1-rc.20
oxc-parser
5 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • oxc-parser@0.112.0

  • root@
    • @unocss/nuxt@66.6.7
      • unocss@66.6.7
        • @unocss/transformer-attributify-jsx@66.6.7
          • oxc-parser@0.115.0

  • root@
    • knip@6.0.5
      • oxc-parser@0.120.0

  • root@
    • nuxt-og-image@6.4.3
      • oxc-parser@0.126.0

  • root@
    • @nuxtjs/i18n@10.2.3
      • oxc-parser@0.95.0

@oxc-parser/binding-wasm32-wasi
5 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • oxc-parser@0.112.0
          • @oxc-parser/binding-wasm32-wasi@0.112.0

  • root@
    • @unocss/nuxt@66.6.7
      • unocss@66.6.7
        • @unocss/transformer-attributify-jsx@66.6.7
          • oxc-parser@0.115.0
            • @oxc-parser/binding-wasm32-wasi@0.115.0

  • root@
    • knip@6.0.5
      • oxc-parser@0.120.0
        • @oxc-parser/binding-wasm32-wasi@0.120.0

  • root@
    • nuxt-og-image@6.4.3
      • oxc-parser@0.126.0
        • @oxc-parser/binding-wasm32-wasi@0.126.0

  • root@
    • @nuxtjs/i18n@10.2.3
      • oxc-parser@0.95.0
        • @oxc-parser/binding-wasm32-wasi@0.95.0

glob
5 versions
  • root@
    • @nuxt/test-utils@4.0.0
      • @vue/test-utils@2.4.6
        • js-beautify@1.15.4
          • glob@10.5.0

  • root@
    • @vite-pwa/nuxt@1.1.1
      • vite-plugin-pwa@1.2.0
        • workbox-build@7.4.0
          • glob@11.1.0

  • root@
    • @vueuse/nuxt@14.2.1
      • ...
        • nitropack@2.13.3
          • @vercel/nft@1.5.0
            • glob@13.0.6

  • root@
    • vue-i18n-extract@2.0.7
      • dot-object@2.1.5
        • glob@7.2.3

  • root@
    • vue-i18n-extract@2.0.7
      • glob@8.1.0

@rolldown/pluginutils
5 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • ...
        • rollup-plugin-visualizer@7.0.1
          • rolldown@1.0.0-rc.12
            • @rolldown/pluginutils@1.0.0-rc.12

  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • @nuxt/vite-builder@4.3.1
          • @vitejs/plugin-vue-jsx@5.1.5
            • @rolldown/pluginutils@1.0.0-rc.13

  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • @nuxt/vite-builder@4.3.1
          • @vitejs/plugin-vue@6.0.5
            • @rolldown/pluginutils@1.0.0-rc.2

  • root@
    • @nuxt/a11y@1.0.0-alpha.1
      • @nuxt/devtools-kit@3.2.4
        • vite@8.0.0-beta.18
          • rolldown@1.0.0-rc.8
            • @rolldown/pluginutils@1.0.0-rc.8

@rolldown/pluginutils@1.0.0-rc.9
@oxc-project/types
7 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • oxc-parser@0.112.0
          • @oxc-project/types@0.112.0

  • root@
    • @nuxt/a11y@1.0.0-alpha.1
      • @nuxt/devtools-kit@3.2.4
        • vite@8.0.0-beta.18
          • rolldown@1.0.0-rc.8
            • @oxc-project/types@0.115.0

  • root@
    • knip@6.0.5
      • oxc-parser@0.120.0
        • @oxc-project/types@0.120.0

  • root@
    • @vueuse/nuxt@14.2.1
      • ...
        • rollup-plugin-visualizer@7.0.1
          • rolldown@1.0.0-rc.12
            • @oxc-project/types@0.122.0

  • root@
    • vite-plus@0.1.16
      • @oxc-project/types@0.123.0

  • root@
    • nuxt-og-image@6.4.3
      • oxc-parser@0.126.0
        • @oxc-project/types@0.126.0

  • root@
    • @nuxtjs/i18n@10.2.3
      • oxc-parser@0.95.0
        • @oxc-project/types@0.95.0

@oxc-parser/binding-android-arm64
5 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • oxc-parser@0.112.0
          • @oxc-parser/binding-android-arm64@0.112.0

  • root@
    • @unocss/nuxt@66.6.7
      • unocss@66.6.7
        • @unocss/transformer-attributify-jsx@66.6.7
          • oxc-parser@0.115.0
            • @oxc-parser/binding-android-arm64@0.115.0

  • root@
    • knip@6.0.5
      • oxc-parser@0.120.0
        • @oxc-parser/binding-android-arm64@0.120.0

  • root@
    • nuxt-og-image@6.4.3
      • oxc-parser@0.126.0
        • @oxc-parser/binding-android-arm64@0.126.0

  • root@
    • @nuxtjs/i18n@10.2.3
      • oxc-parser@0.95.0
        • @oxc-parser/binding-android-arm64@0.95.0

@oxc-parser/binding-darwin-arm64
5 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • oxc-parser@0.112.0
          • @oxc-parser/binding-darwin-arm64@0.112.0

  • root@
    • @unocss/nuxt@66.6.7
      • unocss@66.6.7
        • @unocss/transformer-attributify-jsx@66.6.7
          • oxc-parser@0.115.0
            • @oxc-parser/binding-darwin-arm64@0.115.0

  • root@
    • knip@6.0.5
      • oxc-parser@0.120.0
        • @oxc-parser/binding-darwin-arm64@0.120.0

  • root@
    • nuxt-og-image@6.4.3
      • oxc-parser@0.126.0
        • @oxc-parser/binding-darwin-arm64@0.126.0

  • root@
    • @nuxtjs/i18n@10.2.3
      • oxc-parser@0.95.0
        • @oxc-parser/binding-darwin-arm64@0.95.0

@oxc-parser/binding-darwin-x64
5 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • oxc-parser@0.112.0
          • @oxc-parser/binding-darwin-x64@0.112.0

  • root@
    • @unocss/nuxt@66.6.7
      • unocss@66.6.7
        • @unocss/transformer-attributify-jsx@66.6.7
          • oxc-parser@0.115.0
            • @oxc-parser/binding-darwin-x64@0.115.0

  • root@
    • knip@6.0.5
      • oxc-parser@0.120.0
        • @oxc-parser/binding-darwin-x64@0.120.0

  • root@
    • nuxt-og-image@6.4.3
      • oxc-parser@0.126.0
        • @oxc-parser/binding-darwin-x64@0.126.0

  • root@
    • @nuxtjs/i18n@10.2.3
      • oxc-parser@0.95.0
        • @oxc-parser/binding-darwin-x64@0.95.0

@oxc-parser/binding-freebsd-x64
5 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • oxc-parser@0.112.0
          • @oxc-parser/binding-freebsd-x64@0.112.0

  • root@
    • @unocss/nuxt@66.6.7
      • unocss@66.6.7
        • @unocss/transformer-attributify-jsx@66.6.7
          • oxc-parser@0.115.0
            • @oxc-parser/binding-freebsd-x64@0.115.0

  • root@
    • knip@6.0.5
      • oxc-parser@0.120.0
        • @oxc-parser/binding-freebsd-x64@0.120.0

  • root@
    • nuxt-og-image@6.4.3
      • oxc-parser@0.126.0
        • @oxc-parser/binding-freebsd-x64@0.126.0

  • root@
    • @nuxtjs/i18n@10.2.3
      • oxc-parser@0.95.0
        • @oxc-parser/binding-freebsd-x64@0.95.0

@oxc-parser/binding-linux-arm-gnueabihf
5 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • oxc-parser@0.112.0
          • @oxc-parser/binding-linux-arm-gnueabihf@0.112.0

  • root@
    • @unocss/nuxt@66.6.7
      • unocss@66.6.7
        • @unocss/transformer-attributify-jsx@66.6.7
          • oxc-parser@0.115.0
            • @oxc-parser/binding-linux-arm-gnueabihf@0.115.0

  • root@
    • knip@6.0.5
      • oxc-parser@0.120.0
        • @oxc-parser/binding-linux-arm-gnueabihf@0.120.0

  • root@
    • nuxt-og-image@6.4.3
      • oxc-parser@0.126.0
        • @oxc-parser/binding-linux-arm-gnueabihf@0.126.0

  • root@
    • @nuxtjs/i18n@10.2.3
      • oxc-parser@0.95.0
        • @oxc-parser/binding-linux-arm-gnueabihf@0.95.0

@oxc-parser/binding-linux-arm-musleabihf
5 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • oxc-parser@0.112.0
          • @oxc-parser/binding-linux-arm-musleabihf@0.112.0

  • root@
    • @unocss/nuxt@66.6.7
      • unocss@66.6.7
        • @unocss/transformer-attributify-jsx@66.6.7
          • oxc-parser@0.115.0
            • @oxc-parser/binding-linux-arm-musleabihf@0.115.0

  • root@
    • knip@6.0.5
      • oxc-parser@0.120.0
        • @oxc-parser/binding-linux-arm-musleabihf@0.120.0

  • root@
    • nuxt-og-image@6.4.3
      • oxc-parser@0.126.0
        • @oxc-parser/binding-linux-arm-musleabihf@0.126.0

  • root@
    • @nuxtjs/i18n@10.2.3
      • oxc-parser@0.95.0
        • @oxc-parser/binding-linux-arm-musleabihf@0.95.0

@oxc-parser/binding-linux-arm64-gnu
5 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • oxc-parser@0.112.0
          • @oxc-parser/binding-linux-arm64-gnu@0.112.0

  • root@
    • @unocss/nuxt@66.6.7
      • unocss@66.6.7
        • @unocss/transformer-attributify-jsx@66.6.7
          • oxc-parser@0.115.0
            • @oxc-parser/binding-linux-arm64-gnu@0.115.0

  • root@
    • knip@6.0.5
      • oxc-parser@0.120.0
        • @oxc-parser/binding-linux-arm64-gnu@0.120.0

  • root@
    • nuxt-og-image@6.4.3
      • oxc-parser@0.126.0
        • @oxc-parser/binding-linux-arm64-gnu@0.126.0

  • root@
    • @nuxtjs/i18n@10.2.3
      • oxc-parser@0.95.0
        • @oxc-parser/binding-linux-arm64-gnu@0.95.0

@oxc-parser/binding-linux-arm64-musl
5 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • oxc-parser@0.112.0
          • @oxc-parser/binding-linux-arm64-musl@0.112.0

  • root@
    • @unocss/nuxt@66.6.7
      • unocss@66.6.7
        • @unocss/transformer-attributify-jsx@66.6.7
          • oxc-parser@0.115.0
            • @oxc-parser/binding-linux-arm64-musl@0.115.0

  • root@
    • knip@6.0.5
      • oxc-parser@0.120.0
        • @oxc-parser/binding-linux-arm64-musl@0.120.0

  • root@
    • nuxt-og-image@6.4.3
      • oxc-parser@0.126.0
        • @oxc-parser/binding-linux-arm64-musl@0.126.0

  • root@
    • @nuxtjs/i18n@10.2.3
      • oxc-parser@0.95.0
        • @oxc-parser/binding-linux-arm64-musl@0.95.0

@oxc-parser/binding-linux-riscv64-gnu
5 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • oxc-parser@0.112.0
          • @oxc-parser/binding-linux-riscv64-gnu@0.112.0

  • root@
    • @unocss/nuxt@66.6.7
      • unocss@66.6.7
        • @unocss/transformer-attributify-jsx@66.6.7
          • oxc-parser@0.115.0
            • @oxc-parser/binding-linux-riscv64-gnu@0.115.0

  • root@
    • knip@6.0.5
      • oxc-parser@0.120.0
        • @oxc-parser/binding-linux-riscv64-gnu@0.120.0

  • root@
    • nuxt-og-image@6.4.3
      • oxc-parser@0.126.0
        • @oxc-parser/binding-linux-riscv64-gnu@0.126.0

  • root@
    • @nuxtjs/i18n@10.2.3
      • oxc-parser@0.95.0
        • @oxc-parser/binding-linux-riscv64-gnu@0.95.0

@oxc-parser/binding-linux-s390x-gnu
5 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • oxc-parser@0.112.0
          • @oxc-parser/binding-linux-s390x-gnu@0.112.0

  • root@
    • @unocss/nuxt@66.6.7
      • unocss@66.6.7
        • @unocss/transformer-attributify-jsx@66.6.7
          • oxc-parser@0.115.0
            • @oxc-parser/binding-linux-s390x-gnu@0.115.0

  • root@
    • knip@6.0.5
      • oxc-parser@0.120.0
        • @oxc-parser/binding-linux-s390x-gnu@0.120.0

  • root@
    • nuxt-og-image@6.4.3
      • oxc-parser@0.126.0
        • @oxc-parser/binding-linux-s390x-gnu@0.126.0

  • root@
    • @nuxtjs/i18n@10.2.3
      • oxc-parser@0.95.0
        • @oxc-parser/binding-linux-s390x-gnu@0.95.0

@oxc-parser/binding-linux-x64-gnu
5 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • oxc-parser@0.112.0
          • @oxc-parser/binding-linux-x64-gnu@0.112.0

  • root@
    • @unocss/nuxt@66.6.7
      • unocss@66.6.7
        • @unocss/transformer-attributify-jsx@66.6.7
          • oxc-parser@0.115.0
            • @oxc-parser/binding-linux-x64-gnu@0.115.0

  • root@
    • knip@6.0.5
      • oxc-parser@0.120.0
        • @oxc-parser/binding-linux-x64-gnu@0.120.0

  • root@
    • nuxt-og-image@6.4.3
      • oxc-parser@0.126.0
        • @oxc-parser/binding-linux-x64-gnu@0.126.0

  • root@
    • @nuxtjs/i18n@10.2.3
      • oxc-parser@0.95.0
        • @oxc-parser/binding-linux-x64-gnu@0.95.0

@oxc-parser/binding-linux-x64-musl
5 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • oxc-parser@0.112.0
          • @oxc-parser/binding-linux-x64-musl@0.112.0

  • root@
    • @unocss/nuxt@66.6.7
      • unocss@66.6.7
        • @unocss/transformer-attributify-jsx@66.6.7
          • oxc-parser@0.115.0
            • @oxc-parser/binding-linux-x64-musl@0.115.0

  • root@
    • knip@6.0.5
      • oxc-parser@0.120.0
        • @oxc-parser/binding-linux-x64-musl@0.120.0

  • root@
    • nuxt-og-image@6.4.3
      • oxc-parser@0.126.0
        • @oxc-parser/binding-linux-x64-musl@0.126.0

  • root@
    • @nuxtjs/i18n@10.2.3
      • oxc-parser@0.95.0
        • @oxc-parser/binding-linux-x64-musl@0.95.0

@oxc-parser/binding-win32-arm64-msvc
5 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • oxc-parser@0.112.0
          • @oxc-parser/binding-win32-arm64-msvc@0.112.0

  • root@
    • @unocss/nuxt@66.6.7
      • unocss@66.6.7
        • @unocss/transformer-attributify-jsx@66.6.7
          • oxc-parser@0.115.0
            • @oxc-parser/binding-win32-arm64-msvc@0.115.0

  • root@
    • knip@6.0.5
      • oxc-parser@0.120.0
        • @oxc-parser/binding-win32-arm64-msvc@0.120.0

  • root@
    • nuxt-og-image@6.4.3
      • oxc-parser@0.126.0
        • @oxc-parser/binding-win32-arm64-msvc@0.126.0

  • root@
    • @nuxtjs/i18n@10.2.3
      • oxc-parser@0.95.0
        • @oxc-parser/binding-win32-arm64-msvc@0.95.0

@oxc-parser/binding-win32-x64-msvc
5 versions
  • root@
    • @vueuse/nuxt@14.2.1
      • nuxt@4.3.1
        • oxc-parser@0.112.0
          • @oxc-parser/binding-win32-x64-msvc@0.112.0

  • root@
    • @unocss/nuxt@66.6.7
      • unocss@66.6.7
        • @unocss/transformer-attributify-jsx@66.6.7
          • oxc-parser@0.115.0
            • @oxc-parser/binding-win32-x64-msvc@0.115.0

  • root@
    • knip@6.0.5
      • oxc-parser@0.120.0
        • @oxc-parser/binding-win32-x64-msvc@0.120.0

  • root@
    • nuxt-og-image@6.4.3
      • oxc-parser@0.126.0
        • @oxc-parser/binding-win32-x64-msvc@0.126.0

  • root@
    • @nuxtjs/i18n@10.2.3
      • oxc-parser@0.95.0
        • @oxc-parser/binding-win32-x64-msvc@0.95.0

💡 To find out what depends on a specific package, run: pnpm -r why example-package

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

Comment thread modules/blog.ts
const atomPath = 'atom.xml'
const jsonFeedPath = 'feed.json'

await Promise.all([
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe instead of saving these files to disk, creating pre-rendered server-side routes could be a cleaner approach 🤔. Similar to server/routes/opensearch.xml.get.ts with https://nuxt.com/docs/4.x/getting-started/prerendering#selective-pre-rendering

Copy link
Copy Markdown
Contributor Author

@Kiwow Kiwow Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like exactly what I was looking for and didn't find. Thanks!

I'll add a mention of this to the PR description and look into it when I have time to work on this again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RSS support for the blog

2 participants