payloadcms / payloadcms/payload
withPayload: scope the client-hint header injection to the admin route instead of '/:path*'
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 44.8k
- Forks
- 4.2k
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 53
Description
withPayload adds Accept-CH / Vary / Critical-CH: Sec-CH-Prefers-Color-Scheme on source: '/:path*' — every route of the host app (observed in @payloadcms/next@3.88.0, dist/withPayload/withPayload.js). The injection exists so the admin panel can server-render the correct theme without a flash (getRequestTheme reads the hint), which is right — but Critical-CH on public routes makes every cold Chromium navigation discard the response and retry it (an internal 307 to the same URL). For sites that pin a colour scheme and never read the preference, that is a wasted document round trip on every visitor's first page view, and it silently corrupts headless-browser TTFB measurement (the retried response is served from local cache, so the final hop reads ~0 ms).
Since withPayload doesn't currently know the admin route, could the entry be scoped via an option — e.g. accept the admin base path, or a clientHintHeaders: 'admin-only' | 'all' | false — defaulting to today's behaviour for compatibility?
Workaround we ship today: post-process the returned config, moving the injected entry from '/:path*' to '/:path(admin|admin/.*)':
const payloadConfig = withPayload(nextConfig, options)
export default {
...payloadConfig,
headers: async () => scopeClientHintHeadersToAdmin((await payloadConfig.headers?.()) ?? []),
}
Happy to PR the option if the approach is agreeable.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in dist/withPayload/withPayload.js, tracing how withPayload creates the headers entry for '/:path*' and how the admin route is represented. Done means the client-hint injection can be scoped to the admin route without breaking the existing compatibility behavior; the issue does not name a test file.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nextjs, typescript
- Domain
- backend, web-dev
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100