- /sitemap.xml, from the API's /slugs plus the landing and listings: every address in every language, with hreflang and x-default. A 503 when the API is down, rather than a sitemap missing half the site. - /robots.txt, naming the sitemap on whatever domain this is served on. - Slugs renamed in the panel now redirect. The API has always kept the old address the moment one changed; middleware/redirects.ts answers it with a 301, from a list kept for a minute and through outages. - og:url, og:image (the record's own picture, the logo otherwise) and schema.org JSON-LD: Organization on the landing; WebPage, CreativeWork, Person or Service elsewhere. Shared through core/head. - The proxy-derived origin moves to core/origin.ts, used by the page shell, the landing and both server routes. In development only /api/* reaches Nitro, so the two files 404 under `npm start`; they were checked against a production build. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
35 lines
1.1 KiB
TypeScript
35 lines
1.1 KiB
TypeScript
/**
|
|
* `/sitemap.xml`, from the API's `/slugs` — one request for every published
|
|
* address, instead of paging through each collection.
|
|
*
|
|
* Cached like any page: a record published a minute ago can wait a minute to
|
|
* be listed. If the API is down the answer is a 503 rather than a sitemap
|
|
* with half the site missing from it, which a crawler would believe.
|
|
*/
|
|
import {
|
|
defineEventHandler,
|
|
getRequestHeaders,
|
|
setResponseHeader,
|
|
setResponseStatus,
|
|
} from 'h3';
|
|
|
|
import { pireonApi } from '../../app/core/api';
|
|
import { originFromHeaders } from '../../app/core/origin';
|
|
import { buildSitemap } from '../../app/core/sitemap';
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const origin = originFromHeaders(getRequestHeaders(event)) ?? '';
|
|
const { data } = await pireonApi.slugs();
|
|
|
|
if (!data) {
|
|
setResponseStatus(event, 503);
|
|
setResponseHeader(event, 'Cache-Control', 'no-store');
|
|
|
|
return 'Sitemap temporarily unavailable';
|
|
}
|
|
|
|
setResponseHeader(event, 'Content-Type', 'application/xml; charset=utf-8');
|
|
|
|
return buildSitemap(origin, data);
|
|
});
|