diff --git a/.changeset/five-moose-push.md b/.changeset/five-moose-push.md new file mode 100644 index 000000000000..95859fcca0b4 --- /dev/null +++ b/.changeset/five-moose-push.md @@ -0,0 +1,5 @@ +--- +'@astrojs/rss': patch +--- + +Fix missing type-attribute in xml-stylesheet diff --git a/packages/astro-rss/src/index.ts b/packages/astro-rss/src/index.ts index 4d87586c3222..3bac3feb27f6 100644 --- a/packages/astro-rss/src/index.ts +++ b/packages/astro-rss/src/index.ts @@ -104,7 +104,8 @@ export async function generateRSS({ rssOptions, items }: GenerateRSSArgs): Promi const parser = new XMLParser(xmlOptions); const root: any = { '?xml': { '@_version': '1.0', '@_encoding': 'UTF-8' } }; if (typeof rssOptions.stylesheet === 'string') { - root['?xml-stylesheet'] = { '@_href': rssOptions.stylesheet, '@_encoding': 'UTF-8' }; + const isXSL = /\.xsl$/i.test(rssOptions.stylesheet); + root['?xml-stylesheet'] = { '@_href': rssOptions.stylesheet, ...(isXSL && { '@_type': 'text/xsl' }) }; } root.rss = { '@_version': '2.0' }; if (items.find((result) => result.content)) { diff --git a/packages/astro-rss/test/rss.test.js b/packages/astro-rss/test/rss.test.js index c66c11eb6cc7..95a0bbf10cbd 100644 --- a/packages/astro-rss/test/rss.test.js +++ b/packages/astro-rss/test/rss.test.js @@ -47,6 +47,10 @@ const validXmlResult = `<![CDATA[${title}]]>${site}/<![CDATA[${phpFeedItemWithContent.title}]]>${site}${phpFeedItemWithContent.link}/${site}${phpFeedItemWithContent.link}/${new Date(phpFeedItemWithContent.pubDate).toUTCString()}<![CDATA[${web1FeedItemWithContent.title}]]>${site}${web1FeedItemWithContent.link}/${site}${web1FeedItemWithContent.link}/${new Date(web1FeedItemWithContent.pubDate).toUTCString()}`; // prettier-ignore const validXmlWithCustomDataResult = `<![CDATA[${title}]]>${site}/<![CDATA[${phpFeedItemWithCustomData.title}]]>${site}${phpFeedItemWithCustomData.link}/${site}${phpFeedItemWithCustomData.link}/${new Date(phpFeedItemWithCustomData.pubDate).toUTCString()}${phpFeedItemWithCustomData.customData}<![CDATA[${web1FeedItemWithContent.title}]]>${site}${web1FeedItemWithContent.link}/${site}${web1FeedItemWithContent.link}/${new Date(web1FeedItemWithContent.pubDate).toUTCString()}`; +// prettier-ignore +const validXmlWithStylesheet = `<![CDATA[${title}]]>${site}/`; +// prettier-ignore +const validXmlWithXSLStylesheet = `<![CDATA[${title}]]>${site}/`; describe('rss', () => { it('should generate on valid RSSFeedItem array', async () => { @@ -85,6 +89,30 @@ describe('rss', () => { chai.expect(body).xml.to.equal(validXmlWithCustomDataResult); }); + it('should include xml-stylesheet instruction when stylesheet is defined', async () => { + const { body } = await rss({ + title, + description, + items: [], + site, + stylesheet: '/feedstylesheet.css', + }); + + chai.expect(body).xml.to.equal(validXmlWithStylesheet); + }); + + it('should include xml-stylesheet instruction with xsl type when stylesheet is set to xsl file', async () => { + const { body } = await rss({ + title, + description, + items: [], + site, + stylesheet: '/feedstylesheet.xsl', + }); + + chai.expect(body).xml.to.equal(validXmlWithXSLStylesheet); + }); + describe('glob result', () => { it('should generate on valid result', async () => { const globResult = {