diff --git a/package-lock.json b/package-lock.json index 10dc403..14cff12 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,8 @@ "remark-html": "^16.0.1", "sass": "^1.77.8", "sharp": "^0.33.4", - "swr": "^2.2.5" + "swr": "^2.2.5", + "xml-formatter": "^3.6.3" }, "devDependencies": { "@types/node": "^20", @@ -7701,6 +7702,25 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, + "node_modules/xml-formatter": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-3.6.3.tgz", + "integrity": "sha512-++x1TlRO1FRlQ82AZ4WnoCSufaI/PT/sycn4K8nRl4gnrNC1uYY2VV/67aALZ2m0Q4Q/BLj/L69K360Itw9NNg==", + "dependencies": { + "xml-parser-xo": "^4.1.2" + }, + "engines": { + "node": ">= 16" + } + }, + "node_modules/xml-parser-xo": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/xml-parser-xo/-/xml-parser-xo-4.1.3.tgz", + "integrity": "sha512-U6eN5Pyrlek9ottHVpT9e8YUax75oVYXbnYxU+utzDC7i+OyWj9ynsNMiZNQZvpuazbG0O7iLAs9FkcFmzlgSA==", + "engines": { + "node": ">= 16" + } + }, "node_modules/yaml": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", diff --git a/package.json b/package.json index a4940d2..9ab53a5 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "private": true, "scripts": { "dev": "next dev", + "prebuild": "node scripts/generate-rss.js", "build": "next build", "start": "next start", "lint": "next lint" @@ -23,7 +24,8 @@ "remark-html": "^16.0.1", "sass": "^1.77.8", "sharp": "^0.33.4", - "swr": "^2.2.5" + "swr": "^2.2.5", + "xml-formatter": "^3.6.3" }, "devDependencies": { "@types/node": "^20", diff --git a/scripts/generate-rss.js b/scripts/generate-rss.js new file mode 100644 index 0000000..50d9bcc --- /dev/null +++ b/scripts/generate-rss.js @@ -0,0 +1,49 @@ +const fs = require("fs"); +const path = require("path"); +const matter = require("gray-matter"); +const { format } = require("date-fns"); + +const xmlFormat = require("xml-formatter"); + +const BLOGS_DIR = path.join(process.cwd(), "_blogs"); +const OUTPUT_FILE = path.join(process.cwd(), "public", "rss.xml"); + +function escapeXML(str) { + return str + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/'/g, "'") + .replace(/"/g, """); +} + +function generateRSS() { + const files = fs.readdirSync(BLOGS_DIR); + + const posts = files.map((file) => { + const filePath = path.join(BLOGS_DIR, file); + const content = fs.readFileSync(filePath, "utf-8"); + const { data } = matter(content); + return { + title: data.title, + description: data.excerpt, + link: `https://umairjibran.com/blogs/${file.replace(/\.md$/, "")}`, + pubDate: data.date, + }; + }); + + const rssItems = posts + .map( + (post) => + `${escapeXML(post.title)}${escapeXML(post.link)}${escapeXML(post.description)}${new Date(post.pubDate).toUTCString()}${post.link}`, + ) + .join(""); + + const rssFeed = + `Umair Jibran's Bloghttps://umairjibran.com/blogsLatest articles from Umair Jibran's blog.en-us${new Date().toUTCString()}${rssItems}`.trim(); + + fs.writeFileSync(OUTPUT_FILE, xmlFormat(rssFeed), "utf-8"); + console.log(`RSS feed generated at ${OUTPUT_FILE}`); +} + +generateRSS(); diff --git a/src/app/layout.tsx b/src/app/layout.tsx index ee6d897..f4ea008 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -24,6 +24,11 @@ const inconsolata = Inconsolata({ export const metadata: Metadata = { ...meta, metadataBase: new URL(meta.metadataBase), + alternates: { + types: { + "application/rss+xml": "/rss.xml", + }, + }, }; export default function RootLayout({