Skip to content

Commit 60ffe04

Browse files
Fix RSS enclosure media types (#1135)
* Fix RSS enclosure media types * Limit RSS media detection to paths
1 parent bb9e7ef commit 60ffe04

2 files changed

Lines changed: 38 additions & 1 deletion

File tree

src/routes/rss[.]xml.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,19 @@ function escapeXml(unsafe: string): string {
1212
.replace(/'/g, ''')
1313
}
1414

15+
export function getRssImageMediaType(src: string) {
16+
const path = src.split(/[?#]/, 1)[0]
17+
const extension = path.match(/\.([^./]+)$/)?.[1]?.toLowerCase()
18+
19+
if (extension === 'jpg' || extension === 'jpeg') return 'image/jpeg'
20+
if (extension === 'webp') return 'image/webp'
21+
if (extension === 'svg') return 'image/svg+xml'
22+
if (extension === 'gif') return 'image/gif'
23+
if (extension === 'png') return 'image/png'
24+
25+
return 'application/octet-stream'
26+
}
27+
1528
function generateRSSFeed() {
1629
const posts = getPublishedPosts().slice(0, 50) // Most recent 50 posts
1730
const siteUrl = 'https://tanstack.com'
@@ -42,7 +55,7 @@ function generateRSSFeed() {
4255
<pubDate>${pubDate}</pubDate>
4356
<author>${escapeXml(author)}</author>
4457
<description>${escapeXml(description)}</description>
45-
${post.headerImage ? `<enclosure url="${escapeXml(siteUrl + post.headerImage)}" type="image/png" />` : ''}
58+
${post.headerImage ? `<enclosure url="${escapeXml(siteUrl + post.headerImage)}" type="${getRssImageMediaType(post.headerImage)}" />` : ''}
4659
</item>`
4760
})
4861
.join('')

tests/rss.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import assert from 'node:assert/strict'
2+
import test from 'node:test'
3+
import { getRssImageMediaType } from '../src/routes/rss[.]xml'
4+
5+
test('uses the image media type matching an RSS enclosure URL', () => {
6+
assert.equal(getRssImageMediaType('/header.png'), 'image/png')
7+
assert.equal(getRssImageMediaType('/header.jpg'), 'image/jpeg')
8+
assert.equal(getRssImageMediaType('/header.jpeg'), 'image/jpeg')
9+
assert.equal(getRssImageMediaType('/header.webp'), 'image/webp')
10+
assert.equal(getRssImageMediaType('/header.svg?v=1'), 'image/svg+xml')
11+
assert.equal(getRssImageMediaType('/header.gif#image'), 'image/gif')
12+
assert.equal(
13+
getRssImageMediaType('/header?source=original.png'),
14+
'application/octet-stream',
15+
)
16+
assert.equal(
17+
getRssImageMediaType('/header#preview.jpg'),
18+
'application/octet-stream',
19+
)
20+
assert.equal(
21+
getRssImageMediaType('/header.unknown'),
22+
'application/octet-stream',
23+
)
24+
})

0 commit comments

Comments
 (0)