Skip to content

Commit

Permalink
✨ Add RSS feed for latest news #1988
Browse files Browse the repository at this point in the history
  • Loading branch information
fernandolucchesi committed Dec 5, 2023
1 parent 2cb4246 commit 6c23421
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 6 deletions.
1 change: 1 addition & 0 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"@equinor/eds-tokens": "^0.9.0",
"@next/bundle-analyzer": "^12.1.0",
"@portabletext/react": "^3.0.0",
"@portabletext/to-html": "^2.0.5",
"@portabletext/types": "^2.0.2",
"@react-spring/web": "^9.4.5",
"@sanity/asset-utils": "^1.3.0",
Expand Down
24 changes: 24 additions & 0 deletions web/pages/api/rss/groq.global.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ImageWithCaptionData } from '../../../types'
import { ingressForNewsQuery } from '../../../lib/queries/common/newsSubqueries'
import { publishDateTimeQuery } from '../../../lib/queries/common/publishDateTime'
import { PortableTextBlock } from '@portabletext/types'

export type LatestNewsType = {
_id: string
slug: string
title: string
publishDateTime: string
hero: ImageWithCaptionData
ingress: PortableTextBlock
}

export const latestNews = /* groq */ `
*[_type == "news" && _lang == $lang ][0...20] | order(${publishDateTimeQuery} desc) {
_id,
"slug": slug.current,
title,
"hero": heroImage,
"publishDateTime": ${publishDateTimeQuery},
${ingressForNewsQuery},
}
`
78 changes: 78 additions & 0 deletions web/pages/api/rss/index.global.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { sanityClient } from '../../../lib/sanity.server'
import { LatestNewsType, latestNews } from './groq.global'
import { defaultComponents, toHTML } from '@portabletext/to-html'
import { urlFor } from '../../../common/helpers/urlFor'
import type { NextApiRequest, NextApiResponse } from 'next'

const generateRssFeed = async (lang: 'no' | 'en') => {
try {
const map = {
en: {
language: 'en_GB',
title: 'Equinor News',
description: 'Latest news',
},
no: {
language: 'nb_NO',
title: 'Equinor Nyheter',
description: 'Siste nytt',
},
}
const languageCode = map[lang].language || 'en_GB'

const articles: LatestNewsType[] = await sanityClient.fetch(latestNews, { lang: languageCode })
let rss = `<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>${map[lang].title}</title>
<description>${map[lang].description}</description>
<language>${lang}</language>
<link>https://www.equinor.com</link>`

const serializers = {
...defaultComponents,
marks: {
...defaultComponents.marks,
sub: ({ children }: { children: string }) => `<sub>${children}</sub>`,
sup: ({ children }: { children: string }) => `<sup>${children}</sup>`,
},
}

articles.forEach((article) => {
const descriptionHtml = toHTML(article.ingress, {
components: serializers,
onMissingComponent: (e) => String(e),
})

const hero = article.hero
const bannerImageUrl = hero?.image?.asset ? urlFor(hero.image).size(560, 280).auto('format').toString() : ''
const imageAlt = hero?.image?.alt ? ` alt="${hero.image.alt}"` : ''

rss += `
<item>
<title>${article.title}</title>
<link>https://equinor.com${article.slug}</link>
<guid>https://equinor.com${article.slug}</guid>
<pubDate>${new Date(article.publishDateTime).toUTCString()}</pubDate>
<description><![CDATA[<img src="${bannerImageUrl}"${imageAlt}/><br/>${descriptionHtml}]]></description>
</item>`
})

rss += `
</channel>
</rss>`

return rss
} catch (error) {
console.error('Error generating RSS feed:', error)
throw new Error('Failed to generate RSS feed.')
}
}

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const lang = req.query.lang === 'no' ? 'no' : 'en' // Defaults to 'en' if the lang parameter is not 'no'
const rss = await generateRssFeed(lang)
res.setHeader('Content-Type', 'text/xml')
res.write(rss)
res.end()
}
35 changes: 29 additions & 6 deletions web/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6c23421

Please sign in to comment.