Repository navigation
RSS Improvements #8544
Description
Activity
- addedcontentIssues/pr concerning contentIssues/pr concerning content
on Jan 13, 2026 I looked into this a bit, I think the
Node.js® is a free, open-source, cross-platform...is not coming from the RSS config, but rather the RSS is pointing to a page which Slack (or other tools which perform link previews) is reading ametatag from. Themetatag looks to be driven from the individual article'sdescriptionfrontmatter property, or if none exists then the site'sdescriptionproperty.My notes on how all this flows together
https://nodejs.org/en/feed/blog.xml contains this object:
<title> <![CDATA[ Node.js 22.22.0 (LTS) ]]> </title> <link>https://nodejs.org/en/blog/release/v22.22.0</link> <guid isPermaLink="false">/blog/release/v22.22.0?1768313889314</guid> <pubDate>Tue, 13 Jan 2026 14:18:09 GMT</pubDate> </item>
Grabbing https://nodejs.org/en/blog/release/v22.22.0 contains the page description in the
<meta name="description" content="..." />tag:
For the blog specifically, that metadata is being generated into Next.js using a
generateMetadataexport:nodejs.org/apps/site/app/[locale]/blog/[...path]/page.tsx
Lines 17 to 20 in f0cb063
// This generates each page's HTML Metadata // @see https://nextjs.org/docs/app/api-reference/functions/generate-metadata export const generateMetadata = ({ params }: PageParams) => basePage.generateMetadata({ params, prefix: 'blog' }); nodejs.org/apps/site/next.dynamic.page.mjs
Lines 26 to 44 in f0cb063
/** * This generates each page's HTML Metadata * * @see https://nextjs.org/docs/app/api-reference/functions/generate-metadata * * @param {{ params: Promise<{ path: Array<string>; locale: string }>, prefix?: string }} props * @returns {Promise<import('next').Metadata>} the metadata for the page */ export const generateMetadata = async ({ params, prefix }) => { const { path = [], locale = defaultLocale.code } = await params; const pathname = dynamicRouter.getPathname(path); return dynamicRouter.getPageMetadata( locale, // If there's a prefix, `join` it with the pathname prefix ? join(prefix, pathname) : pathname ); }; nodejs.org/apps/site/next.dynamic.mjs
Lines 188 to 262 in f0cb063
/** * This method generates the Next.js App Router Metadata * that can be used for each page to provide metadata * * @param {string} locale * @param {string} path * @returns {Promise<import('next').Metadata>} */ const _getPageMetadata = async (locale = defaultLocale.code, path = '') => { const pageMetadata = { ...PAGE_METADATA }; const { source = '' } = await getMarkdownFile(locale, path); const { data } = matter(source); const getUrlForPathname = (l, p) => `${baseUrlAndPath}/${l}${p ? `/${p}` : ''}`; // Default Title for the page pageMetadata.title = data.title ? `${siteConfig.title} — ${data.title}` : siteConfig.title; pageMetadata.description = data.description ? data.description : siteConfig.description; // Default Twitter Title for the page pageMetadata.twitter.title = pageMetadata.title; // Default Open Graph Image for the page pageMetadata.openGraph.images = [ ENABLE_STATIC_EXPORT ? `${defaultLocale.code}/next-data/og/announcement/Run JavaScript Everywhere` : `${defaultLocale.code}/next-data/og/${data.category ?? DEFAULT_CATEGORY_OG_TYPE}/${pageMetadata.title}`, ]; // Default canonical URL for the page pageMetadata.alternates.canonical = data.canonical ?? getUrlForPathname(locale, path); // Default alternate URL for the page in the default locale pageMetadata.alternates.languages['x-default'] = getUrlForPathname( defaultLocale.code, path ); // Retrieves a matching blog feed for the category of the blog post // If no matching blog feed is found, we simply fallback to the default blog feed const matchingBlogFeed = siteConfig.rssFeeds.find( feed => feed.category === data.category ); // Adds the RSS Feed URL to the page metadata, if a matching feed is found // otherwise, we fallback to the default blog feed pageMetadata.alternates.types['application/rss+xml'] = getUrlForPathname( locale, `feed/${matchingBlogFeed?.file ?? 'blog.xml'}` ); // Iterate all languages to generate alternate URLs for each language availableLocaleCodes.forEach(currentLocale => { pageMetadata.alternates.languages[currentLocale] = getUrlForPathname( currentLocale, path ); }); return pageMetadata; }; // Creates a Cached Version of the Page Metadata Context const getPageMetadata = cache(async (locale, path) => { return await _getPageMetadata(locale, path); }); Data from
_getPageMetadatais either sourced from the specific markdown article's frontmatter content or from the entire site's config:nodejs.org/apps/site/site.json
Line 3 in f0cb063
"description": "Node.js® is a free, open-source, cross-platform JavaScript runtime environment that lets developers create servers, web apps, command line tools and scripts.", Well, the problem is that we don't really have summaries for our blog posts. Just the content, and authors aren't used on writing summaries.
We could source the first paragraph form the article itself ... but not sure if that'd be a good idea.
so we'd have to institute a process change for releasers to write some sort of top-level description, right? certainly puts a bit of a wrench in the automation
Reacted by Claudio WunderMaybe we could generate summaries with AI
Maybe we could generate summaries with AI
That'd be a bit expensive... Where would we store them or when to generate them?
so we'd have to institute a process change for releasers to write some sort of top-level description, right? certainly puts a bit of a wrench in the automation
🫠
Maybe we could generate summaries with AI
That'd be a bit expensive... Where would we store them or when to generate them?
Why expensive? The posts aren't that long. We can automate this using actions and can save the result on the post's frontmatter
Maybe we could generate summaries with AI
That'd be a bit expensive... Where would we store them or when to generate them?
Why expensive? The posts aren't that long. We can automate this using actions and can save the result on the post's frontmatter
Who paying the AI bill, you?
Reacted by Guilherme AraújoCause automated (non-human-originating) AI agentic/task usage is against the ToS of pretty much every provider out there.
👀 I think we'd be fine to set the RSS description to the first paragraph of the article, with links + markup stripped out.
let's try Matt idea it's seem good idea
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fields📋 Backlog
Enter your suggestions in details:
I got feedback that RSS posts would be useful if they had more preview context. For example, this is what blasts into Slack...
I haven't looked at other feed experiences. It could be variable.