Files
landing-app/landing/src/server/routes/blog/rss.xml.get.ts
pigui fea60a168c Add a blog, built from pages
A post is a page in the panel's "Blog" category, so it is written,
translated, scheduled and reviewed like any page, and the MCP server
can publish one the same way. Nothing new in the API.

- /blog (/en/blog, /ca/blog): posts newest first, with image, date and
  excerpt.
- A post shows its date and leads back to the blog; its structured data
  is a BlogPosting.
- /blog/rss.xml?lang=xx: one feed per language, announced in <head>.
- Posts stay out of the header and the footer, which links the blog
  once there is any post instead of growing with every one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 15:45:08 +02:00

55 lines
1.4 KiB
TypeScript

/**
* `/blog/rss.xml?lang=xx`: the blog as RSS, in one language — a feed reader
* subscribes to one, and a post only has the addresses of the languages it was
* translated into.
*/
import {
defineEventHandler,
getQuery,
getRequestHeaders,
setResponseHeader,
setResponseStatus,
} from 'h3';
import { pireonApi, resolveLocale } from '../../../app/core/api';
import { BLOG_CATEGORY, byPublication } from '../../../app/core/blog';
import { copyFor } from '../../../app/core/copy';
import { originFromHeaders } from '../../../app/core/origin';
import { listingPath } from '../../../app/core/routes';
import { buildFeed } from '../../../app/core/rss';
export default defineEventHandler(async (event) => {
const locale = resolveLocale(getQuery(event)['lang']);
const origin = originFromHeaders(getRequestHeaders(event)) ?? '';
const copy = copyFor(locale);
const { data, error } = await pireonApi.pages(locale, {
category: BLOG_CATEGORY[locale],
per_page: 50,
});
if (error) {
setResponseStatus(event, 503);
setResponseHeader(event, 'Cache-Control', 'no-store');
return 'Feed temporarily unavailable';
}
setResponseHeader(
event,
'Content-Type',
'application/rss+xml; charset=utf-8',
);
return buildFeed(
origin,
locale,
{
title: `Pireon — ${copy.blog.title}`,
description: copy.blog.lead,
link: listingPath('blog', locale),
},
byPublication(data ?? []),
);
});