diff --git a/nuxt.config.ts b/nuxt.config.ts index 76ab537..2d5787d 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -3,6 +3,12 @@ export default defineNuxtConfig({ devtools: { enabled: true }, srcDir: './src', + nitro: { + prerender: { + routes: ['/blog/feed.xml'] + } + }, + modules: [ '@nuxt/eslint', '@nuxt/fonts', diff --git a/package-lock.json b/package-lock.json index 1409499..6ed2e47 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "@nuxt/icon": "^1.11.0", "@nuxtjs/i18n": "^9.5.3", "eslint": "^9.24.0", + "feed": "^4.2.2", "nuxt": "^3.16.2", "vue": "^3.5.13", "vue-router": "^4.5.0" @@ -7642,6 +7643,18 @@ } } }, + "node_modules/feed": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", + "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", + "license": "MIT", + "dependencies": { + "xml-js": "^1.6.11" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -13507,6 +13520,12 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "license": "ISC" + }, "node_modules/scslre": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/scslre/-/scslre-0.3.0.tgz", @@ -16167,6 +16186,18 @@ } } }, + "node_modules/xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "license": "MIT", + "dependencies": { + "sax": "^1.2.4" + }, + "bin": { + "xml-js": "bin/cli.js" + } + }, "node_modules/xml-name-validator": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", diff --git a/package.json b/package.json index 38930ca..6f25454 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@nuxt/icon": "^1.11.0", "@nuxtjs/i18n": "^9.5.3", "eslint": "^9.24.0", + "feed": "^4.2.2", "nuxt": "^3.16.2", "vue": "^3.5.13", "vue-router": "^4.5.0" diff --git a/.old/public/assets/images/opengraph/opengraph-image.png b/src/public/assets/images/opengraph/opengraph-image.png similarity index 100% rename from .old/public/assets/images/opengraph/opengraph-image.png rename to src/public/assets/images/opengraph/opengraph-image.png diff --git a/src/server/routes/blog/feed.xml.ts b/src/server/routes/blog/feed.xml.ts new file mode 100644 index 0000000..62eb00c --- /dev/null +++ b/src/server/routes/blog/feed.xml.ts @@ -0,0 +1,45 @@ +import { Feed } from 'feed'; + +export default defineEventHandler(async (event) => { + const allPosts = await queryCollection(event, 'blog').all(); + + const posts = allPosts.filter(p => !p.path.startsWith('/blog/_')).sort((a, b) => { + return new Date(b.date).getTime() - new Date(a.date).getTime(); + }); + + const feed = new Feed({ + title: 'Pretendo Network Blog', + description: 'The latest updates in condensed chunks', + updated: new Date(posts[0].date), + id: 'http://pretendo.network/', + link: 'https://pretendo.network/blog/', + image: 'https://pretendo.network/assets/images/opengraph/opengraph-image.png', + favicon: 'http://pretendo.network/favicon.ico', + copyright: 'Pretendo Network', + feedLinks: { + atom: 'https://pretendo.network/blog/rss.xml' + } + }); + + posts.forEach((post) => { + feed.addItem({ + title: post.title, + id: post.path, + link: `https://pretendo.network/${post.path}`, + description: post.caption, + author: [ + { + name: post.author + } + ], + date: new Date(post.date), + image: `https://pretendo.network/${post.cover_image}` + }); + }); + + feed.addCategory('Technology'); + + event.res.setHeader('content-type', 'text/xml'); + + return feed.rss2(); +});