The rendering split is dictated by CI building with no database. /blog, /blog/rss.xml and /content-sitemap.xml have no dynamic params, so Next prerenders them at build time and the build fails on a missing Payload secret — caught here, not on staging. They are force-dynamic instead: one indexed query against Postgres on the same Docker network, and a newly published post appears immediately rather than waiting on a revalidation. /blog/[slug] keeps ISR, because with no generateStaticParams there is nothing to prerender; it is generated on first request and cached, which is exactly what the collection's afterChange hook exists to invalidate. RichText takes `converters`, not `blocks`, in Payload 3.88, and the default converters must be spread or every paragraph and heading loses its renderer and the body comes out empty. BlogPosting references the Person and Organization by @id rather than repeating them, so every post and the About page resolve to one author entity instead of declaring several people with the same name. /sitemap.xml is proxied from FastAPI, which knows nothing about Payload, so the Next-owned URLs get their own sitemap and robots.txt lists both. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017YmbBhr8s7GusjDE12hrZM
21 lines
644 B
TypeScript
21 lines
644 B
TypeScript
import robots from '@/app/robots';
|
|
|
|
describe('robots.txt', () => {
|
|
it('disallows the admin panel and the CMS API', () => {
|
|
const rules = robots().rules;
|
|
const rule = Array.isArray(rules) ? rules[0] : rules;
|
|
expect(rule.disallow).toEqual(
|
|
expect.arrayContaining(['/api/', '/_next/', '/admin/', '/cms-api/']),
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('sitemap discovery', () => {
|
|
it('lists both the proxied school sitemap and the Next-owned content sitemap', () => {
|
|
expect(robots().sitemap).toEqual([
|
|
'https://www.schoolcompare.co.uk/sitemap.xml',
|
|
'https://www.schoolcompare.co.uk/content-sitemap.xml',
|
|
]);
|
|
});
|
|
});
|