[Next.js] HTTP localhost repeats development-browser handshake three times
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 1.8k
- Forks
- 472
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 189
Description
Preliminary Checks
- I have reviewed the relevant Clerk documentation, including the SDK development terminology for handshakes and development-instance cookies: https://clerk.com/docs/guides/development/sdk-development/terminology
- I have searched existing
clerk/javascriptissues forDevBrowserMissing, repeated localhost handshakes,__clerk_db_jwt, andSameSite/Securecombinations. - No email or Discord support request was opened as part of preparing this report.
- This is a bug report directly related to Clerk's JavaScript packages, not a general support question.
Reproduction
Publishable key
pk_test_aGVscGVkLW95c3Rlci01Ny5jbGVyay5hY2NvdW50cy5kZXYk
Description
A cold guest navigation to a public page on plain HTTP localhost repeatedly enters Clerk's development-browser handshake path. The reproduction is a fresh, standalone Next.js App Router application containing only ClerkProvider, clerkMiddleware, one public page, and a Playwright measurement. It has no application business logic, database, login flow, testing tokens, or mocks.
Steps to reproduce:
-
Clone the reproduction at the exact commit linked above.
-
Copy
.env.exampleto.env.localand provide the included development instance's publishable and secret keys locally. The secret key is not committed or included in this report. -
Install and build:
bun install --frozen-lockfile bunx playwright install chromium bun run build -
Run five fresh-browser-context repetitions:
bun run test:repro -- --repeat-each=5
The command is expected to exit with code 1 when the bug reproduces because the final assertion requires at most one handshake; the page itself still reaches HTTP 200.
Expected behavior:
One cold guest navigation to / should reach the public page with at most one /v1/client/handshake document request.
Actual behavior:
The problem reproduced in 5/5 fresh Chromium contexts. Every single page.goto("/") produced:
- exactly 3 document requests whose pathname was
/v1/client/handshake; - 9 HTTP 307 document responses;
- a final HTTP 200 response on
/.
The Node-observed redirect-prefix durations were 1087, 729, 704, 748, and 710 ms (median 729 ms). The corresponding navigation-to-load durations were 1287, 934, 890, 940, and 902 ms (median 934 ms). These are observations from this machine, not a latency benchmark or a claim that any particular change guarantees an improvement.
The responses set __clerk_db_jwt with SameSite=None and without the Secure attribute. The missing Secure attribute is a measured response fact. A browser refusing to persist or return that cookie and thereby causing the repeated handshake is a causal hypothesis, not established by this reproduction. Likewise, this report does not claim that HTTPS would fix the issue.
The test records only sanitized URL origins/pathnames, statuses, Clerk header names, cookie names/attribute names, request counts, and monotonic timings. Raw Playwright traces remain ignored and are not published.
Environment
System:
OS: macOS 26.6.2
CPU: (8) arm64 Apple M2
Binaries:
Node: 24.14.1
npm: 11.19.1
bun: 1.4.0
Browsers installed on the host:
Chrome: 152.0.7977.83
Edge: 153.0.4234.32
Firefox: 155.0.1
Safari: 26.6.2
Browser used by the verified Playwright run:
Chromium: 151.0.7922.34
npmPackages (pinned to match the application where the behavior was observed; not claimed to be latest):
@clerk/nextjs: 7.7.6
@clerk/backend override: 3.16.6
@clerk/react override: 6.14.3
@clerk/shared override: 4.29.1
@playwright/test: 1.62.1
next: 16.3.1
react: 0.0.0-experimental-eafeac09-20260819
react-dom: 0.0.0-experimental-eafeac09-20260819
typescript: 7.0.2
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 with the linked reproduction at the pinned commit, follow its .env.example setup, and run bun run test:repro -- --repeat-each=5 after bun run build. Inspect the /v1/client/handshake requests, 307 responses, and __clerk_db_jwt cookie behavior. Done means a cold guest navigation to / produces at most one handshake and still reaches the public page.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- next.js, playwright, typescript
- Domain
- authentication, web-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 64/100