fix(nextjs): forward CSP nonce as request header in clerkMiddleware#7828
fix(nextjs): forward CSP nonce as request header in clerkMiddleware#7828jacekradko merged 2 commits intomainfrom
Conversation
When using `clerkMiddleware({ contentSecurityPolicy: { strict: true } })`,
the generated nonce was only set as a response header but never forwarded
as a request header via `x-middleware-override-headers`. This meant
`headers()` in server components couldn't read the nonce, so
`ClerkProvider`'s `getNonceHeaders()` returned empty and Next.js couldn't
apply the nonce to its `<script>` tags — breaking `strict-dynamic` CSP.
Forward CSP headers (including `x-nonce`) as request headers using
`setRequestHeadersOnNextResponse` so server components can access them.
Also update the integration template to use the built-in CSP option.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: acf04f8 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
!snapshot |
@clerk/agent-toolkit
@clerk/astro
@clerk/backend
@clerk/chrome-extension
@clerk/clerk-js
@clerk/dev-cli
@clerk/expo
@clerk/expo-passkeys
@clerk/express
@clerk/fastify
@clerk/hono
@clerk/localizations
@clerk/nextjs
@clerk/nuxt
@clerk/react
@clerk/react-router
@clerk/shared
@clerk/tanstack-react-start
@clerk/testing
@clerk/ui
@clerk/upgrade
@clerk/vue
commit: |
|
Hey @jacekradko - the snapshot version command generated the following package versions:
Tip: Use the snippet copy button below to quickly install the required packages. npm i @clerk/agent-toolkit@0.3.0-snapshot.v20260212160100 --save-exact
npm i @clerk/astro@3.0.0-snapshot.v20260212160100 --save-exact
npm i @clerk/backend@3.0.0-snapshot.v20260212160100 --save-exact
npm i @clerk/chrome-extension@3.0.0-snapshot.v20260212160100 --save-exact
npm i @clerk/clerk-js@6.0.0-snapshot.v20260212160100 --save-exact
npm i @clerk/dev-cli@1.0.0-snapshot.v20260212160100 --save-exact
npm i @clerk/expo@3.0.0-snapshot.v20260212160100 --save-exact
npm i @clerk/expo-passkeys@1.0.0-snapshot.v20260212160100 --save-exact
npm i @clerk/express@2.0.0-snapshot.v20260212160100 --save-exact
npm i @clerk/fastify@2.7.0-snapshot.v20260212160100 --save-exact
npm i @clerk/localizations@4.0.0-snapshot.v20260212160100 --save-exact
npm i @clerk/msw@0.0.1-snapshot.v20260212160100 --save-exact
npm i @clerk/nextjs@7.0.0-snapshot.v20260212160100 --save-exact
npm i @clerk/nuxt@2.0.0-snapshot.v20260212160100 --save-exact
npm i @clerk/react@6.0.0-snapshot.v20260212160100 --save-exact
npm i @clerk/react-router@3.0.0-snapshot.v20260212160100 --save-exact
npm i @clerk/shared@4.0.0-snapshot.v20260212160100 --save-exact
npm i @clerk/tanstack-react-start@1.0.0-snapshot.v20260212160100 --save-exact
npm i @clerk/testing@2.0.0-snapshot.v20260212160100 --save-exact
npm i @clerk/ui@1.0.0-snapshot.v20260212160100 --save-exact
npm i @clerk/upgrade@2.0.0-snapshot.v20260212160100 --save-exact
npm i @clerk/vue@2.0.0-snapshot.v20260212160100 --save-exact |
📝 WalkthroughWalkthroughThe changes implement CSP nonce forwarding in the Clerk Next.js middleware. A changeset is added for a patch release. The next-app-router template middleware is updated to pass 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. No actionable comments were generated in the recent review. 🎉 Comment |
Summary
x-nonce) as request headers viasetRequestHeadersOnNextResponseinclerkMiddleware, soheaders()in server components can read the noncecontentSecurityPolicy: { strict: true }option instead of a manual CSP stringProblem
When using
clerkMiddleware({ contentSecurityPolicy: { strict: true } }), the generated nonce was only set as a response header (x-nonce,content-security-policy). It was never forwarded as a request header via thex-middleware-override-headersmechanism. This meant:headers()in server components couldn't read the nonceClerkProvider'sgetNonceHeaders()returned''<script>tagsstrict-dynamic, browsers ignore'self', so unnonced scripts got blockedThe manual approach (setting CSP on
req.headers) worked becausedecorateRequestcopies request headers. The built-in option bypassed this path.Test plan
pnpm buildpassespnpm testinpackages/nextjs— all 108 tests pass (including 2 new CSP forwarding tests)git diff main --statshows only intended filesSummary by CodeRabbit
Bug Fixes
Tests