build(next): convert the config to ESM so Payload can wrap it
withPayload() is ESM-only, so next.config.js has to become .mjs. That file also carries the rule that keeps staging out of Google's index, so the conversion goes in on its own, behind a test that asserts the rule survived — along with the standalone output, the opengraph-image font tracing and the analytics frame-ancestors CSP. Jest resolves the .mjs config without extra configuration, so jest.config.js is untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017YmbBhr8s7GusjDE12hrZM
This commit is contained in:
1 parent
74e5fffc10
commit
eb648f3f76
2 files changed
+50
-1
No files matched your search
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* next.config.mjs carries the staging noindex rule. Breaking it turns
|
||||
* stx.schoolcompare.co.uk into a fully crawlable duplicate of production,
|
||||
* and nothing else in the suite would notice.
|
||||
*
|
||||
* The non-null assertions are deliberate: every key asserted here is optional
|
||||
* on NextConfig, and a missing one is precisely the regression under test, so
|
||||
* the assertion below should fail the test rather than the compile.
|
||||
*/
|
||||
import nextConfig from '@/next.config.mjs';
|
||||
|
||||
async function headerRules() {
|
||||
return nextConfig.headers!();
|
||||
}
|
||||
|
||||
describe('next.config.mjs', () => {
|
||||
it('keeps the staging host out of the index', async () => {
|
||||
const headers = await headerRules();
|
||||
const stagingRule = headers.find((rule) =>
|
||||
rule.has?.some(
|
||||
(cond) => cond.type === 'host' && cond.value === 'stx.schoolcompare.co.uk',
|
||||
),
|
||||
);
|
||||
expect(stagingRule).toBeDefined();
|
||||
expect(stagingRule!.headers).toContainEqual({
|
||||
key: 'X-Robots-Tag',
|
||||
value: 'noindex, nofollow',
|
||||
});
|
||||
});
|
||||
|
||||
it('still emits standalone output for the Docker runner', () => {
|
||||
expect(nextConfig.output).toBe('standalone');
|
||||
});
|
||||
|
||||
it('still traces the share-card fonts into the standalone bundle', () => {
|
||||
expect(nextConfig.outputFileTracingIncludes!['/opengraph-image']).toEqual([
|
||||
'./assets/**',
|
||||
]);
|
||||
});
|
||||
|
||||
it('still allows the analytics subdomain to frame the site', async () => {
|
||||
const headers = await headerRules();
|
||||
const csp = headers
|
||||
.flatMap((rule) => rule.headers)
|
||||
.find((header) => header.key === 'Content-Security-Policy');
|
||||
expect(csp).toBeDefined();
|
||||
expect(csp!.value).toContain('https://analytics.schoolcompare.co.uk');
|
||||
});
|
||||
});
|
||||
@@ -127,4 +127,4 @@ const nextConfig = {
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = nextConfig;
|
||||
export default nextConfig;
|
||||
Reference in new issue
Block a user