Мой сайт-портфолио создан с помощью Nuxt 3 и Nuxt Content v2. RSS-канал с пятью последними записями из моего блога доступен здесь. В этой статье вы узнаете, как добавить RSS-канал на ваш сайт Nuxt.
Настройка
Сначала давайте создадим новый проект Nuxt 3. Следующим шагом нам нужно добавить модуль Nuxt Content v2 в наше приложение.
Наконец, давайте добавим контент, который будет включен в RSS-ленту:
├── content
| └── blog
| └── blog
| | ├── article-1.md
| | ├── article-2.md
| | ├── article-3.md
| | ├── article-4.md
| | ├── article-5.md
Каждый файл .md
имеет такую простую структуру:
---
title: 'Article 1'
description: 'Article 1 description'
date: '2022-01-01'
---
Article 5 Content
Исходный код этого демо доступен на GitHub и на этой площадке StackBlitz:
Добавление серверного маршрута
Мы будем использовать серверные маршруты, доступные в Nuxt, и для этого нам нужно создать каталог server/
непосредственно в корне нашего приложения.
После этого мы создадим каталог routes/
и добавим в него файл rss.xml.ts
. Он будет переведен в /rss.xml
:
export default defineEventHandler(async (event) => {
const feedString = ''
event.res.setHeader('content-type', 'text/xml')
event.res.end(feedString)
})
Следующим шагом будет запрос записей нашего блога:
import { serverQueryContent } from '#content/server'
export default defineEventHandler(async (event) => {
const docs = await serverQueryContent(event).sort({ date: -1 }).where({ _partial: false }).find()
const blogPosts = docs.filter((doc) => doc?._path?.includes('/blog'))
const feedString = ''
event.res.setHeader('content-type', 'text/xml')
event.res.end(feedString)
})
Теперь добавим библиотеку rss для создания XML-строки RSS на основе нашего контента:
import { serverQueryContent } from '#content/server'
import RSS from 'rss'
const feed = new RSS({
title: 'Michael Hoffmann',
site_url: 'https://mokkapps.de',
feed_url: `https://mokkapps.de/rss.xml`,
})
const docs = await serverQueryContent(event).sort({ date: -1 }).where({ _partial: false }).find()
const blogPosts = docs.filter((doc) => doc?._path?.includes('/blog'))
for (const doc of blogPosts) {
feed.item({
title: doc.title ?? '-',
url: `https://mokkapps.de${doc._path}`,
date: doc.date,
description: doc.description,
})
}
const feedString = feed.xml({ indent: true })
event.res.setHeader('content-type', 'text/xml')
event.res.end(feedString)
При использовании nuxt generate
, вы можете захотеть предварительно отрендерить ленту, так как серверный маршрут не сможет работать на статическом хостинге.
Это можно сделать с помощью опции nitro.prerender
в nuxt.config
:
import { defineNuxtConfig } from 'nuxt'
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
modules: ['@nuxt/content'],
nitro: {
prerender: {
routes: ['/rss.xml'],
},
},
content: {
// https://content.nuxtjs.org/api/configuration
},
})
Если мы теперь перейдем к /rss.xml
, то получим сгенерированную RSS ленту:
<rss xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
<channel>
<title>
<![CDATA[ Michael Hoffmann ]]>
</title>
<description>
<![CDATA[ Michael Hoffmann ]]>
</description>
<link>https://mokkapps.de</link>
<generator>RSS for Node</generator>
<lastBuildDate>Sun, 14 Aug 2022 18:14:16 GMT</lastBuildDate>
<atom:link href="https://mokkapps.de/rss.xml" rel="self" type="application/rss+xml"/>
<item>
<title>
<![CDATA[ Article 5 ]]>
</title>
<description>
<![CDATA[ Article 5 description ]]>
</description>
<link>https://mokkapps.de/blog/article-5</link>
<guid isPermaLink="true">https://mokkapps.de/blog/article-5</guid>
<pubDate>Thu, 05 May 2022 00:00:00 GMT</pubDate>
</item>
<item>
<title>
<![CDATA[ Article 4 ]]>
</title>
<description>
<![CDATA[ Article 4 description ]]>
</description>
<link>https://mokkapps.de/blog/article-4</link>
<guid isPermaLink="true">https://mokkapps.de/blog/article-4</guid>
<pubDate>Mon, 04 Apr 2022 00:00:00 GMT</pubDate>
</item>
<item>
<title>
<![CDATA[ Article 3 ]]>
</title>
<description>
<![CDATA[ Article 3 description ]]>
</description>
<link>https://mokkapps.de/blog/article-3</link>
<guid isPermaLink="true">https://mokkapps.de/blog/article-3</guid>
<pubDate>Thu, 03 Mar 2022 00:00:00 GMT</pubDate>
</item>
<item>
<title>
<![CDATA[ Article 2 ]]>
</title>
<description>
<![CDATA[ Article 2 description ]]>
</description>
<link>https://mokkapps.de/blog/article-2</link>
<guid isPermaLink="true">https://mokkapps.de/blog/article-2</guid>
<pubDate>Wed, 02 Feb 2022 00:00:00 GMT</pubDate>
</item>
<item>
<title>
<![CDATA[ Article 1 ]]>
</title>
<description>
<![CDATA[ Article 1 description ]]>
</description>
<link>https://mokkapps.de/blog/article-1</link>
<guid isPermaLink="true">https://mokkapps.de/blog/article-1</guid>
<pubDate>Sat, 01 Jan 2022 00:00:00 GMT</pubDate>
</item>
</channel>
</rss>
Если вам понравилась эта статья, следуйте за мной в Twitter, чтобы получать уведомления о новых статьях блога и других материалах от меня.
Также (или дополнительно) вы можете подписаться на мою рассылку.