canina/frontend/application/app/blog/rss.xml/route.ts
parsa aghaei 5705354429
All checks were successful
Deploy Canina / deploy (push) Successful in 1m43s
feat(blog): complete full-stack blog module with rich text editor, SEO analyzer, JSON-LD schema, and RSS feed
2026-08-24 16:48:31 +03:30

83 lines
3.0 KiB
TypeScript

import { NextResponse } from 'next/server';
export const dynamic = 'force-dynamic';
export async function GET() {
const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://canina.ir';
const apiUrl = process.env.INTERNAL_API_URL || process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4001/api';
const apiBase = apiUrl.endsWith('/api') ? apiUrl : `${apiUrl.replace(/\/$/, '')}/api`;
let blogs: any[] = [];
try {
const res = await fetch(`${apiBase}/blogs?page=1&limit=50`, { next: { revalidate: 3600 } });
if (res.ok) {
const data = await res.json();
blogs = (data.data || []).filter((b: any) => !b.noIndex && b.status === 'PUBLISHED');
}
} catch (e) {
console.error('Error fetching blogs for RSS feed:', e);
}
const itemsXml = blogs
.map((b) => {
const title = escapeXml(b.title || '');
const link = `${baseUrl}/blog/${b.slug}`;
const description = escapeXml(b.excerpt || b.metaDescription || '');
const pubDate = b.publishedAt ? new Date(b.publishedAt).toUTCString() : b.createdAt ? new Date(b.createdAt).toUTCString() : new Date().toUTCString();
const author = escapeXml(b.author ? `${b.author.firstName || ''} ${b.author.lastName || ''}`.trim() : 'کنینا فارما');
const category = escapeXml(b.category?.name || 'دانشنامه سلامت حیوانات');
return `
<item>
<title>${title}</title>
<link>${link}</link>
<guid isPermaLink="true">${link}</guid>
<description><![CDATA[${description}]]></description>
<pubDate>${pubDate}</pubDate>
<author>${author}</author>
<category>${category}</category>
${b.imageUrl ? `<enclosure url="${b.imageUrl.startsWith('http') ? b.imageUrl : `${baseUrl}${b.imageUrl}`}" type="image/jpeg" />` : ''}
</item>`;
})
.join('');
const rssFeed = `<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>مجله سلامت و دانشنامه تخصصی کنینا (Canina Pharma)</title>
<link>${baseUrl}/blog</link>
<description>جدیدترین مقالات علمی در زمینه مکمل‌های تخصصی، تغذیه و سلامت سگ و گربه از داروسازی کنینا آلمان</description>
<language>fa-ir</language>
<lastBuildDate>${new Date().toUTCString()}</lastBuildDate>
<atom:link href="${baseUrl}/blog/rss.xml" rel="self" type="application/rss+xml"/>
${itemsXml}
</channel>
</rss>`;
return new NextResponse(rssFeed, {
headers: {
'Content-Type': 'application/xml; charset=utf-8',
'Cache-Control': 'public, s-maxage=3600, stale-while-revalidate=86400',
},
});
}
function escapeXml(unsafe: string): string {
return unsafe.replace(/[<>&'"]/g, (c) => {
switch (c) {
case '<':
return '&lt;';
case '>':
return '&gt;';
case '&':
return '&amp;';
case '\'':
return '&apos;';
case '"':
return '&quot;';
default:
return c;
}
});
}