Skip to content

feat(plugin-rss): add final output transform hook for atom/rss/json#3238

Merged
SoonIter merged 2 commits intomainfrom
copilot/featureexclude-md-mdx-and-modify-xml
Mar 25, 2026
Merged

feat(plugin-rss): add final output transform hook for atom/rss/json#3238
SoonIter merged 2 commits intomainfrom
copilot/featureexclude-md-mdx-and-modify-xml

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 17, 2026

@rspress/plugin-rss already supports filtering pages via test, but it could not customize the final serialized feed output. This made it hard to inject extra channel/feed metadata such as custom IDs required by some feed consumers while keeping one configuration model across RSS, Atom, and JSON Feed.

  • Add final-output customization hook

    • Introduces output.transform on FeedOutputOptions.
    • Runs after feed serialization and before the file is written.
    • Works uniformly for rss, atom, and json outputs.
  • Keep configuration precedence predictable

    • Supports transform at both:
      • plugin-level output
      • per-feed output
    • Per-feed transform overrides the top-level one, matching existing output option behavior.
  • Clarify filtering and callback docs

    • Documents the function-form test callback as the recommended way to include a route prefix while excluding specific pages such as /blog/.
    • Aligns the documented test / item callback signatures with the current implementation.
  • Document cross-format customization

    • Adds English and Chinese docs for the new hook with a single customization pattern that applies to XML and JSON feeds.

Example:

pluginRss({
  siteUrl: 'https://example.com/',
  output: {
    transform(content, { type, channel }) {
      if (type === 'json') {
        return JSON.stringify({
          ...JSON.parse(content),
          foloId: channel.id,
        });
      }

      const closingTag = type === 'rss' ? '</channel>' : '</feed>';
      return content.replace(
        closingTag,
        `<folo:id>${channel.id}</folo:id>${closingTag}`,
      );
    },
  },
});

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • accounts.google.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --mute-audio --crashpad-handler-pid=5242 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/playwright_chromiumdev_profile-gXhtxK --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,1635927436449698563,13978106266449576955,262144 --enable-features=CDPScreenshotNewSurface --disable-features=AutoDeElevate,AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,OptimizationHints,PaintHolding,Rend (dns block)
    • Triggering command: /opt/google/chrome/chrome /opt/google/chrome/chrome --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Transl bin/node (dns block)
  • clients2.google.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --mute-audio --crashpad-handler-pid=5242 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/playwright_chromiumdev_profile-gXhtxK --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,1635927436449698563,13978106266449576955,262144 --enable-features=CDPScreenshotNewSurface --disable-features=AutoDeElevate,AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,OptimizationHints,PaintHolding,Rend (dns block)
    • Triggering command: /opt/google/chrome/chrome /opt/google/chrome/chrome --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Transl bin/node (dns block)
  • safebrowsingohttpgateway.googleapis.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --mute-audio --crashpad-handler-pid=5242 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/playwright_chromiumdev_profile-gXhtxK --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,1635927436449698563,13978106266449576955,262144 --enable-features=CDPScreenshotNewSurface --disable-features=AutoDeElevate,AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,OptimizationHints,PaintHolding,Rend (dns block)
    • Triggering command: /opt/google/chrome/chrome /opt/google/chrome/chrome --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Transl bin/node (dns block)
  • www.google.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --mute-audio --crashpad-handler-pid=5242 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/playwright_chromiumdev_profile-gXhtxK --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,1635927436449698563,13978106266449576955,262144 --enable-features=CDPScreenshotNewSurface --disable-features=AutoDeElevate,AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,OptimizationHints,PaintHolding,Rend (dns block)
    • Triggering command: /opt/google/chrome/chrome /opt/google/chrome/chrome --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Transl bin/node (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>[Feature]: The rss plug-in adds the function of excluding md/mdx and modifying xml</issue_title>
<issue_description>### What problem does this feature solve?

1、如果不排除index.tsx的情况下,这个文件必须增加date属性
2、如Folo这个应用,需要在rss文件中的channel标签下增加他生成的一个id来确保这个rss的作者

What does the proposed API look like?

我正在构建一个博客的主题,在只用@rspress/plugin-rss插件的时候有两个意见
目前我的博客链接是:https://note-test.tteam.icu/blog/
实现的方式是类似于本文档的博客index.tsx写了个BlogList的组件
以下是两个建议:
1、在PluginRssOptions中增加排除选项
2、增加一个用于在最终rss文件基础上增加参数的配置,或者开放rss模板文件供用户修改

我在未来将会尝试pr去增加</issue_description>

<agent_instructions>"增加一个用于在最终rss文件基础上增加参数的配置,或者开放rss模板文件供用户修改"

尝试修改,'atom' | 'rss' | 'json' 尽量可以用同一套自定义的配置</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@SoonIter What's the difference between "excludes" and "test"? - https://rspress.rs/zh/plugin/official-plugins/rss#test @SoonIter Thanks for your explanation and the case sharing. Have you tried other types of `test` ? Image
  1. RegExp
feed: {
  id: 'blog',
  test: /\/blog\/\w/
}
  1. function
feed: {
  id: 'blog',
  test: (item) => {
        const { routePath } = item;
        return item.routePath.startWith('/blog/') && item.routePath !== '/blog/'
  }
}
```</body></comment_new>
</comments>

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] [Feature] Add exclude option for md/mdx in rss plug-in feat(plugin-rss): add final output transform hook for atom/rss/json Mar 17, 2026
Copilot AI requested a review from SoonIter March 17, 2026 09:16
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 17, 2026

Rsdoctor Bundle Diff Analysis

Found 3 projects in monorepo, 3 projects with changes.

📊 Quick Summary
Project Total Size Change
node 12.5 MB +19.0 KB (0.1%)
web 16.2 MB +21.5 KB (0.1%)
node_md 1.6 MB +4.1 KB (0.3%)
📋 Detailed Reports (Click to expand)

📁 node

Path: website/doc_build/diff-rsdoctor/node/rsdoctor-data.json

📌 Baseline Commit: a9b8bd124a | PR: #3255

Metric Current Baseline Change
📊 Total Size 12.5 MB 12.4 MB +19.0 KB (0.1%)
📄 JavaScript 0 B 0 B 0
🎨 CSS 0 B 0 B 0
🌐 HTML 12.5 MB 12.4 MB +19.0 KB (0.1%)
📁 Other Assets 0 B 0 B 0

📦 Download Diff Report: node Bundle Diff

📁 web

Path: website/doc_build/diff-rsdoctor/web/rsdoctor-data.json

📌 Baseline Commit: a9b8bd124a | PR: #3255

Metric Current Baseline Change
📊 Total Size 16.2 MB 16.2 MB +21.5 KB (0.1%)
📄 JavaScript 15.9 MB 15.9 MB +21.4 KB (0.1%)
🎨 CSS 121.5 KB 121.5 KB 0
🌐 HTML 0 B 0 B 0
📁 Other Assets 166.6 KB 166.5 KB +130.0 B (0.1%)

📦 Download Diff Report: web Bundle Diff

📁 node_md

Path: website/doc_build/diff-rsdoctor/node_md/rsdoctor-data.json

📌 Baseline Commit: a9b8bd124a | PR: #3255

Metric Current Baseline Change
📊 Total Size 1.6 MB 1.6 MB +4.1 KB (0.3%)
📄 JavaScript 0 B 0 B 0
🎨 CSS 0 B 0 B 0
🌐 HTML 0 B 0 B 0
📁 Other Assets 1.6 MB 1.6 MB +4.1 KB (0.3%)

📦 Download Diff Report: node_md Bundle Diff

Generated by Rsdoctor GitHub Action

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages bot commented Mar 17, 2026

Deploying rspress-v2 with  Cloudflare Pages  Cloudflare Pages

Latest commit: 0d31347
Status: ✅  Deploy successful!
Preview URL: https://51afaf67.rspress-v2.pages.dev
Branch Preview URL: https://copilot-featureexclude-md-md.rspress-v2.pages.dev

View logs

@buyfakett
Copy link
Copy Markdown
Contributor

buyfakett commented Mar 25, 2026

I tested that this pr can achieve what I want. My configuration is:

output: {
                    type: 'rss',
                    dir: 'blog',
                    filename: 'rss.xml',
                    transform(content) {
                        const feedId = '123';
                        const userId = '456';

                        const followChallenge = [
                            '<follow_challenge>',
                            `            <feedId>${feedId}</feedId>`,
                            `            <userId>${userId}</userId>`,
                            '        </follow_challenge>',
                        ].join('\n');

                        if (content.includes('<item>')) {
                            return content.replace('<item>', `${followChallenge}\n    <item>`);
                        }

                        return content.replace('</channel>', `${followChallenge}\n  </channel>`);
                    },
                }

This pr can be merged?

@SoonIter SoonIter force-pushed the copilot/featureexclude-md-mdx-and-modify-xml branch from 22f9587 to 327594e Compare March 25, 2026 04:02
@SoonIter SoonIter marked this pull request as ready for review March 25, 2026 04:08
Copilot AI review requested due to automatic review settings March 25, 2026 04:08
@SoonIter SoonIter force-pushed the copilot/featureexclude-md-mdx-and-modify-xml branch from ab6451b to 0d31347 Compare March 25, 2026 04:08
@SoonIter SoonIter enabled auto-merge (squash) March 25, 2026 04:08
@SoonIter SoonIter requested a review from Timeless0911 March 25, 2026 04:08
@SoonIter SoonIter changed the title feat(plugin-rss): add final output transform hook for atom/rss/json feat(plugin-rss): add final output transform hook for atom/rss/json Mar 25, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR extends @rspress/plugin-rss to allow post-processing of the final serialized feed output (RSS/Atom/JSON) via a new output.transform hook, and updates docs/tests accordingly.

Changes:

  • Add output.transform(content, context) to transform serialized feed content before writing to disk, with per-feed override over plugin-level.
  • Update RSS plugin docs (EN/ZH) to reflect current test callback signature/behavior and document the new transform hook with examples.
  • Add automated tests covering transform behavior across output types and precedence.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
website/docs/zh/plugin/official-plugins/rss.mdx Updates ZH docs for test signature/behavior and documents output.transform with example usage.
website/docs/en/plugin/official-plugins/rss.mdx Updates EN docs for test signature/behavior and documents output.transform with example usage.
scripts/dictionary.txt Adds folo to the dictionary to prevent spelling/lint false-positives in docs/tests.
packages/plugin-rss/tests/output.test.ts Adds coverage for transform application across rss/atom/json and override precedence.
packages/plugin-rss/src/type.ts Introduces transform types (FeedOutputTransformer, context) and adds siteUrl to the item callback signature.
packages/plugin-rss/src/plugin-rss.ts Switches file writing to use renderFeedContent(...) so transforms run after serialization.
packages/plugin-rss/src/options.ts Implements renderFeedContent(...) and wires resolved transform into getOutputInfo(...).
packages/plugin-rss/src/internals/type.ts Extends ResolvedOutput to carry the resolved transform function.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@SoonIter SoonIter merged commit 8091665 into main Mar 25, 2026
6 checks passed
@SoonIter SoonIter deleted the copilot/featureexclude-md-mdx-and-modify-xml branch March 25, 2026 04:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: The rss plug-in adds the function of excluding md/mdx and modifying xml

5 participants